Software /
code /
prosody
Comparison
net/server_select.lua @ 9835:20bf5b47c1fb
net.server: New API for creating server listeners
server.listen(interface, port, listeners, options);
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Thu, 13 Sep 2018 21:16:37 +0200 |
parent | 9635:fc2266339cd8 |
child | 9851:75d2874502c3 |
comparison
equal
deleted
inserted
replaced
9834:a657df70cc31 | 9835:20bf5b47c1fb |
---|---|
66 local stats | 66 local stats |
67 local idfalse | 67 local idfalse |
68 local closeall | 68 local closeall |
69 local addsocket | 69 local addsocket |
70 local addserver | 70 local addserver |
71 local listen | |
71 local addtimer | 72 local addtimer |
72 local getserver | 73 local getserver |
73 local wrapserver | 74 local wrapserver |
74 local getsettings | 75 local getsettings |
75 local closesocket | 76 local closesocket |
155 | 156 |
156 _maxsslhandshake = 30 -- max handshake round-trips | 157 _maxsslhandshake = 30 -- max handshake round-trips |
157 | 158 |
158 ----------------------------------// PRIVATE //-- | 159 ----------------------------------// PRIVATE //-- |
159 | 160 |
160 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd | 161 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, ssldirect ) -- this function wraps a server -- FIXME Make sure FD < _maxfd |
161 | 162 |
162 if socket:getfd() >= _maxfd then | 163 if socket:getfd() >= _maxfd then |
163 out_error("server.lua: Disallowed FD number: "..socket:getfd()) | 164 out_error("server.lua: Disallowed FD number: "..socket:getfd()) |
164 socket:close() | 165 socket:close() |
165 return nil, "fd-too-large" | 166 return nil, "fd-too-large" |
242 return false | 243 return false |
243 end | 244 end |
244 local client, err = accept( socket ) -- try to accept | 245 local client, err = accept( socket ) -- try to accept |
245 if client then | 246 if client then |
246 local ip, clientport = client:getpeername( ) | 247 local ip, clientport = client:getpeername( ) |
247 local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx ) -- wrap new client socket | 248 local handler, client, err = wrapconnection( handler, listeners, client, ip, serverport, clientport, pattern, sslctx, ssldirect ) -- wrap new client socket |
248 if err then -- error while wrapping ssl socket | 249 if err then -- error while wrapping ssl socket |
249 return false | 250 return false |
250 end | 251 end |
251 connections = connections + 1 | 252 connections = connections + 1 |
252 out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport)) | 253 out_put( "server.lua: accepted new client connection from ", tostring(ip), ":", tostring(clientport), " to ", tostring(serverport)) |
253 if dispatch and not sslctx then -- SSL connections will notify onconnect when handshake completes | 254 if dispatch and not ssldirect then -- SSL connections will notify onconnect when handshake completes |
254 return dispatch( handler ); | 255 return dispatch( handler ); |
255 end | 256 end |
256 return; | 257 return; |
257 elseif err then -- maybe timeout or something else | 258 elseif err then -- maybe timeout or something else |
258 out_put( "server.lua: error with new client connection: ", tostring(err) ) | 259 out_put( "server.lua: error with new client connection: ", tostring(err) ) |
262 end | 263 end |
263 end | 264 end |
264 return handler | 265 return handler |
265 end | 266 end |
266 | 267 |
267 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object | 268 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx, ssldirect ) -- this function wraps a client to a handler object |
268 | 269 |
269 if socket:getfd() >= _maxfd then | 270 if socket:getfd() >= _maxfd then |
270 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent | 271 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent |
271 socket:close( ) -- Should we send some kind of error here? | 272 socket:close( ) -- Should we send some kind of error here? |
272 if server then | 273 if server then |
664 shutdown = ( ssl and id ) or socket.shutdown | 665 shutdown = ( ssl and id ) or socket.shutdown |
665 | 666 |
666 _socketlist[ socket ] = handler | 667 _socketlist[ socket ] = handler |
667 _readlistlen = addsocket(_readlist, socket, _readlistlen) | 668 _readlistlen = addsocket(_readlist, socket, _readlistlen) |
668 | 669 |
669 if sslctx and has_luasec then | 670 if sslctx and ssldirect and has_luasec then |
670 out_put "server.lua: auto-starting ssl negotiation..." | 671 out_put "server.lua: auto-starting ssl negotiation..." |
671 handler.autostart_ssl = true; | 672 handler.autostart_ssl = true; |
672 local ok, err = handler:starttls(sslctx); | 673 local ok, err = handler:starttls(sslctx); |
673 if ok == false then | 674 if ok == false then |
674 return nil, nil, err | 675 return nil, nil, err |
739 sender:set_mode("*a"); | 740 sender:set_mode("*a"); |
740 end | 741 end |
741 | 742 |
742 ----------------------------------// PUBLIC //-- | 743 ----------------------------------// PUBLIC //-- |
743 | 744 |
744 addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server | 745 listen = function ( addr, port, listeners, config ) |
745 addr = addr or "*" | 746 addr = addr or "*" |
747 config = config or {} | |
746 local err | 748 local err |
749 local sslctx = config.tls_ctx; | |
750 local ssldirect = config.tls_direct; | |
751 local pattern = config.read_size; | |
747 if type( listeners ) ~= "table" then | 752 if type( listeners ) ~= "table" then |
748 err = "invalid listener table" | 753 err = "invalid listener table" |
749 elseif type ( addr ) ~= "string" then | 754 elseif type ( addr ) ~= "string" then |
750 err = "invalid address" | 755 err = "invalid address" |
751 elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then | 756 elseif type( port ) ~= "number" or not ( port >= 0 and port <= 65535 ) then |
762 local server, err = socket_bind( addr, port, _tcpbacklog ) | 767 local server, err = socket_bind( addr, port, _tcpbacklog ) |
763 if err then | 768 if err then |
764 out_error( "server.lua, [", addr, "]:", port, ": ", err ) | 769 out_error( "server.lua, [", addr, "]:", port, ": ", err ) |
765 return nil, err | 770 return nil, err |
766 end | 771 end |
767 local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket | 772 local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, ssldirect ) -- wrap new server socket |
768 if not handler then | 773 if not handler then |
769 server:close( ) | 774 server:close( ) |
770 return nil, err | 775 return nil, err |
771 end | 776 end |
772 server:settimeout( 0 ) | 777 server:settimeout( 0 ) |
773 _readlistlen = addsocket(_readlist, server, _readlistlen) | 778 _readlistlen = addsocket(_readlist, server, _readlistlen) |
774 _server[ addr..":"..port ] = handler | 779 _server[ addr..":"..port ] = handler |
775 _socketlist[ server ] = handler | 780 _socketlist[ server ] = handler |
776 out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" ) | 781 out_put( "server.lua: new "..(sslctx and "ssl " or "").."server listener on '[", addr, "]:", port, "'" ) |
777 return handler | 782 return handler |
783 end | |
784 | |
785 addserver = function( addr, port, listeners, pattern, sslctx ) -- this function provides a way for other scripts to reg a server | |
786 return listen(addr, port, listeners, { | |
787 read_size = pattern; | |
788 tls_ctx = sslctx; | |
789 tls_direct = sslctx and true or false; | |
790 }); | |
778 end | 791 end |
779 | 792 |
780 getserver = function ( addr, port ) | 793 getserver = function ( addr, port ) |
781 return _server[ addr..":"..port ]; | 794 return _server[ addr..":"..port ]; |
782 end | 795 end |
983 end | 996 end |
984 | 997 |
985 --// EXPERIMENTAL //-- | 998 --// EXPERIMENTAL //-- |
986 | 999 |
987 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) | 1000 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) |
988 local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) | 1001 local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx, sslctx) |
989 if not handler then return nil, err end | 1002 if not handler then return nil, err end |
990 _socketlist[ socket ] = handler | 1003 _socketlist[ socket ] = handler |
991 if not sslctx then | 1004 if not sslctx then |
992 _readlistlen = addsocket(_readlist, socket, _readlistlen) | 1005 _readlistlen = addsocket(_readlist, socket, _readlistlen) |
993 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) | 1006 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) |
1119 link = link, | 1132 link = link, |
1120 step = step, | 1133 step = step, |
1121 stats = stats, | 1134 stats = stats, |
1122 closeall = closeall, | 1135 closeall = closeall, |
1123 addserver = addserver, | 1136 addserver = addserver, |
1137 listen = listen, | |
1124 getserver = getserver, | 1138 getserver = getserver, |
1125 setlogger = setlogger, | 1139 setlogger = setlogger, |
1126 getsettings = getsettings, | 1140 getsettings = getsettings, |
1127 setquitting = setquitting, | 1141 setquitting = setquitting, |
1128 removeserver = removeserver, | 1142 removeserver = removeserver, |