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,