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, |