Software /
code /
prosody
Comparison
net/server_select.lua @ 5331:ffa740b4f08d
net.server_select: Limit global number of sockets passed to select.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 12 Feb 2013 03:24:41 +0100 |
parent | 5330:0a0ca2eb991b |
child | 5337:c22dd451487f |
comparison
equal
deleted
inserted
replaced
5330:0a0ca2eb991b | 5331:ffa740b4f08d |
---|---|
120 | 120 |
121 local _cleanqueue | 121 local _cleanqueue |
122 | 122 |
123 local _timer | 123 local _timer |
124 | 124 |
125 local _maxclientsperserver | 125 local _maxselectlen |
126 local _maxfd | |
126 | 127 |
127 local _maxsslhandshake | 128 local _maxsslhandshake |
128 | 129 |
129 ----------------------------------// DEFINITION //-- | 130 ----------------------------------// DEFINITION //-- |
130 | 131 |
154 _sendtimeout = 60000 -- allowed send idle time in secs | 155 _sendtimeout = 60000 -- allowed send idle time in secs |
155 _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs | 156 _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs |
156 | 157 |
157 _cleanqueue = false -- clean bufferqueue after using | 158 _cleanqueue = false -- clean bufferqueue after using |
158 | 159 |
159 _maxclientsperserver = 1000 | 160 _maxfd = luasocket._SETSIZE or 1024 -- We should ignore this on Windows. Perhaps by simply setting it to math.huge or something. |
161 _maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows | |
160 | 162 |
161 _maxsslhandshake = 30 -- max handshake round-trips | 163 _maxsslhandshake = 30 -- max handshake round-trips |
162 | 164 |
163 ----------------------------------// PRIVATE //-- | 165 ----------------------------------// PRIVATE //-- |
164 | 166 |
165 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxconnections ) -- this function wraps a server | 167 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd |
166 | 168 |
167 maxconnections = maxconnections or _maxclientsperserver | 169 if socket:getfd() >= _maxfd then |
170 out_error("server.lua: Disallowed FD number: "..socket:getfd()) | |
171 socket:close() | |
172 return nil, "fd-too-large" | |
173 end | |
168 | 174 |
169 local connections = 0 | 175 local connections = 0 |
170 | 176 |
171 local dispatch, disconnect = listeners.onconnect, listeners.ondisconnect | 177 local dispatch, disconnect = listeners.onconnect, listeners.ondisconnect |
172 | 178 |
231 end | 237 end |
232 handler.socket = function( ) | 238 handler.socket = function( ) |
233 return socket | 239 return socket |
234 end | 240 end |
235 handler.readbuffer = function( ) | 241 handler.readbuffer = function( ) |
236 if connections > maxconnections then | 242 if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then |
237 handler.pause( ) | 243 handler.pause( ) |
238 out_put( "server.lua: refused new client connection: server full" ) | 244 out_put( "server.lua: refused new client connection: server full" ) |
239 return false | 245 return false |
240 end | 246 end |
241 local client, err = accept( socket ) -- try to accept | 247 local client, err = accept( socket ) -- try to accept |
259 return handler | 265 return handler |
260 end | 266 end |
261 | 267 |
262 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 ) -- this function wraps a client to a handler object |
263 | 269 |
270 if socket:getfd() >= _maxfd then | |
271 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent | |
272 socket:close( ) -- Should we send some kind of error here? | |
273 server.pause( ) | |
274 return nil, nil, "fd-too-large" | |
275 end | |
264 socket:settimeout( 0 ) | 276 socket:settimeout( 0 ) |
265 | 277 |
266 --// local import of socket methods //-- | 278 --// local import of socket methods //-- |
267 | 279 |
268 local send | 280 local send |
722 local server, err = socket_bind( addr, port ) | 734 local server, err = socket_bind( addr, port ) |
723 if err then | 735 if err then |
724 out_error( "server.lua, [", addr, "]:", port, ": ", err ) | 736 out_error( "server.lua, [", addr, "]:", port, ": ", err ) |
725 return nil, err | 737 return nil, err |
726 end | 738 end |
727 local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, _maxclientsperserver ) -- wrap new server socket | 739 local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket |
728 if not handler then | 740 if not handler then |
729 server:close( ) | 741 server:close( ) |
730 return nil, err | 742 return nil, err |
731 end | 743 end |
732 server:settimeout( 0 ) | 744 server:settimeout( 0 ) |
766 _socketlist = { } | 778 _socketlist = { } |
767 --mem_free( ) | 779 --mem_free( ) |
768 end | 780 end |
769 | 781 |
770 getsettings = function( ) | 782 getsettings = function( ) |
771 return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxclientsperserver, _maxsslhandshake | 783 return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxselectlen, _maxsslhandshake, _maxfd |
772 end | 784 end |
773 | 785 |
774 changesettings = function( new ) | 786 changesettings = function( new ) |
775 if type( new ) ~= "table" then | 787 if type( new ) ~= "table" then |
776 return nil, "invalid settings table" | 788 return nil, "invalid settings table" |
781 _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen | 793 _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen |
782 _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval | 794 _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval |
783 _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout | 795 _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout |
784 _readtimeout = tonumber( new.read_timeout ) or _readtimeout | 796 _readtimeout = tonumber( new.read_timeout ) or _readtimeout |
785 _cleanqueue = new.select_clean_queue | 797 _cleanqueue = new.select_clean_queue |
786 _maxclientsperserver = new.max_connections or _maxclientsperserver | 798 _maxselectlen = new.max_connections or _maxselectlen |
787 _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake | 799 _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake |
800 _maxfd = new.highest_allowed_fd or _maxfd | |
788 return true | 801 return true |
789 end | 802 end |
790 | 803 |
791 addtimer = function( listener ) | 804 addtimer = function( listener ) |
792 if type( listener ) ~= "function" then | 805 if type( listener ) ~= "function" then |
863 end | 876 end |
864 | 877 |
865 --// EXPERIMENTAL //-- | 878 --// EXPERIMENTAL //-- |
866 | 879 |
867 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) | 880 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) |
868 local handler = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) | 881 local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) |
882 if not handler then return nil, err end | |
869 _socketlist[ socket ] = handler | 883 _socketlist[ socket ] = handler |
870 if not sslctx then | 884 if not sslctx then |
871 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) | 885 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) |
872 if listeners.onconnect then | 886 if listeners.onconnect then |
873 -- When socket is writeable, call onconnect | 887 -- When socket is writeable, call onconnect |