Mercurial > prosody-hg
comparison net/server_event.lua @ 3396:23cf369ed1c3
net.server_event: Fix to not call onconnect a second time after the SSL handshake for starttls connections (thanks Flo)
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Thu, 22 Jul 2010 11:43:42 +0100 |
| parents | ebb8d0f9a177 |
| children | 331547f2393e |
comparison
equal
deleted
inserted
replaced
| 3395:e736f68c1047 | 3396:23cf369ed1c3 |
|---|---|
| 141 self:ontimeout() -- call timeout listener | 141 self:ontimeout() -- call timeout listener |
| 142 self:_close() | 142 self:_close() |
| 143 debug( "new connection failed. id:", self.id, "error:", self.fatalerror ) | 143 debug( "new connection failed. id:", self.id, "error:", self.fatalerror ) |
| 144 else | 144 else |
| 145 if plainssl and ssl then -- start ssl session | 145 if plainssl and ssl then -- start ssl session |
| 146 self:starttls() | 146 self:starttls(nil, true) |
| 147 else -- normal connection | 147 else -- normal connection |
| 148 self:_start_session( self.listener.onconnect ) | 148 self:_start_session(true) |
| 149 end | 149 end |
| 150 debug( "new connection established. id:", self.id ) | 150 debug( "new connection established. id:", self.id ) |
| 151 end | 151 end |
| 152 self.eventconnect = nil | 152 self.eventconnect = nil |
| 153 return -1 | 153 return -1 |
| 154 end | 154 end |
| 155 self.eventconnect = addevent( base, self.conn, EV_WRITE, callback, cfg.CONNECT_TIMEOUT ) | 155 self.eventconnect = addevent( base, self.conn, EV_WRITE, callback, cfg.CONNECT_TIMEOUT ) |
| 156 return true | 156 return true |
| 157 end | 157 end |
| 158 function interface_mt:_start_session(onconnect) -- new session, for example after startssl | 158 function interface_mt:_start_session(call_onconnect) -- new session, for example after startssl |
| 159 if self.type == "client" then | 159 if self.type == "client" then |
| 160 local callback = function( ) | 160 local callback = function( ) |
| 161 self:_lock( false, false, false ) | 161 self:_lock( false, false, false ) |
| 162 --vdebug( "start listening on client socket with id:", self.id ) | 162 --vdebug( "start listening on client socket with id:", self.id ) |
| 163 self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ); -- register callback | 163 self.eventread = addevent( base, self.conn, EV_READ, self.readcallback, cfg.READ_TIMEOUT ); -- register callback |
| 164 self:onconnect() | 164 if call_onconnect then |
| 165 debug("CALLING ONCONNECT") | |
| 166 self:onconnect() | |
| 167 else | |
| 168 debug("NOT CALLING ONCONNECT"); | |
| 169 end | |
| 165 self.eventsession = nil | 170 self.eventsession = nil |
| 166 return -1 | 171 return -1 |
| 167 end | 172 end |
| 168 self.eventsession = addevent( base, nil, EV_TIMEOUT, callback, 0 ) | 173 self.eventsession = addevent( base, nil, EV_TIMEOUT, callback, 0 ) |
| 169 else | 174 else |
| 171 --vdebug( "start listening on server socket with id:", self.id ) | 176 --vdebug( "start listening on server socket with id:", self.id ) |
| 172 self.eventread = addevent( base, self.conn, EV_READ, self.readcallback ) -- register callback | 177 self.eventread = addevent( base, self.conn, EV_READ, self.readcallback ) -- register callback |
| 173 end | 178 end |
| 174 return true | 179 return true |
| 175 end | 180 end |
| 176 function interface_mt:_start_ssl(arg) -- old socket will be destroyed, therefore we have to close read/write events first | 181 function interface_mt:_start_ssl(call_onconnect) -- old socket will be destroyed, therefore we have to close read/write events first |
| 177 --vdebug( "starting ssl session with client id:", self.id ) | 182 --vdebug( "starting ssl session with client id:", self.id ) |
| 178 local _ | 183 local _ |
| 179 _ = self.eventread and self.eventread:close( ) -- close events; this must be called outside of the event callbacks! | 184 _ = self.eventread and self.eventread:close( ) -- close events; this must be called outside of the event callbacks! |
| 180 _ = self.eventwrite and self.eventwrite:close( ) | 185 _ = self.eventwrite and self.eventwrite:close( ) |
| 181 self.eventread, self.eventwrite = nil, nil | 186 self.eventread, self.eventwrite = nil, nil |
| 182 local err | 187 local err |
| 183 self.conn, err = ssl.wrap( self.conn, self._sslctx ) | 188 self.conn, err = ssl.wrap( self.conn, self._sslctx ) |
| 184 if err then | 189 if err then |
| 185 self.fatalerror = err | 190 self.fatalerror = err |
| 186 self.conn = nil -- cannot be used anymore | 191 self.conn = nil -- cannot be used anymore |
| 187 if "onconnect" == arg then | 192 if call_onconnect then |
| 188 self.ondisconnect = nil -- dont call this when client isnt really connected | 193 self.ondisconnect = nil -- dont call this when client isnt really connected |
| 189 end | 194 end |
| 190 self:_close() | 195 self:_close() |
| 191 debug( "fatal error while ssl wrapping:", err ) | 196 debug( "fatal error while ssl wrapping:", err ) |
| 192 return false | 197 return false |
| 209 if not err then | 214 if not err then |
| 210 self:_lock( false, false, false ) -- unlock the interface; sending, closing etc allowed | 215 self:_lock( false, false, false ) -- unlock the interface; sending, closing etc allowed |
| 211 self.send = self.conn.send -- caching table lookups with new client object | 216 self.send = self.conn.send -- caching table lookups with new client object |
| 212 self.receive = self.conn.receive | 217 self.receive = self.conn.receive |
| 213 local onsomething | 218 local onsomething |
| 214 if "onconnect" == arg then -- trigger listener | 219 if not call_onconnect then -- trigger listener |
| 215 onsomething = self.onconnect | 220 self:onstatus("ssl-handshake-complete"); |
| 216 else | |
| 217 onsomething = self.onsslconnection | |
| 218 end | 221 end |
| 219 self:_start_session( onsomething ) | 222 self:_start_session( call_onconnect ) |
| 220 debug( "ssl handshake done" ) | 223 debug( "ssl handshake done" ) |
| 221 self:onstatus("ssl-handshake-complete"); | |
| 222 self.eventhandshake = nil | 224 self.eventhandshake = nil |
| 223 return -1 | 225 return -1 |
| 224 end | 226 end |
| 225 debug( "error during ssl handshake:", err ) | 227 debug( "error during ssl handshake:", err ) |
| 226 if err == "wantwrite" then | 228 if err == "wantwrite" then |
| 230 else | 232 else |
| 231 self.fatalerror = err | 233 self.fatalerror = err |
| 232 end | 234 end |
| 233 end | 235 end |
| 234 if self.fatalerror then | 236 if self.fatalerror then |
| 235 if "onconnect" == arg then | 237 if call_onconnect then |
| 236 self.ondisconnect = nil -- dont call this when client isnt really connected | 238 self.ondisconnect = nil -- dont call this when client isnt really connected |
| 237 end | 239 end |
| 238 self:_close() | 240 self:_close() |
| 239 debug( "handshake failed because:", self.fatalerror ) | 241 debug( "handshake failed because:", self.fatalerror ) |
| 240 self.eventhandshake = nil | 242 self.eventhandshake = nil |
| 412 | 414 |
| 413 function interface_mt:set_send(new_send) | 415 function interface_mt:set_send(new_send) |
| 414 -- No-op, we always use the underlying connection's send | 416 -- No-op, we always use the underlying connection's send |
| 415 end | 417 end |
| 416 | 418 |
| 417 function interface_mt:starttls(sslctx) | 419 function interface_mt:starttls(sslctx, call_onconnect) |
| 418 debug( "try to start ssl at client id:", self.id ) | 420 debug( "try to start ssl at client id:", self.id ) |
| 419 local err | 421 local err |
| 420 self._sslctx = sslctx; | 422 self._sslctx = sslctx; |
| 421 if self._usingssl then -- startssl was already called | 423 if self._usingssl then -- startssl was already called |
| 422 err = "ssl already active" | 424 err = "ssl already active" |
| 426 return nil, err | 428 return nil, err |
| 427 end | 429 end |
| 428 self._usingssl = true | 430 self._usingssl = true |
| 429 self.startsslcallback = function( ) -- we have to start the handshake outside of a read/write event | 431 self.startsslcallback = function( ) -- we have to start the handshake outside of a read/write event |
| 430 self.startsslcallback = nil | 432 self.startsslcallback = nil |
| 431 self:_start_ssl(); | 433 self:_start_ssl(call_onconnect); |
| 432 self.eventstarthandshake = nil | 434 self.eventstarthandshake = nil |
| 433 return -1 | 435 return -1 |
| 434 end | 436 end |
| 435 if not self.eventwrite then | 437 if not self.eventwrite then |
| 436 self:_lock( true, true, true ) -- lock the interface, to not disturb the handshake | 438 self:_lock( true, true, true ) -- lock the interface, to not disturb the handshake |
| 697 local client_ip, client_port = client:getpeername( ) | 699 local client_ip, client_port = client:getpeername( ) |
| 698 interface._connections = interface._connections + 1 -- increase connection count | 700 interface._connections = interface._connections + 1 -- increase connection count |
| 699 local clientinterface = handleclient( client, client_ip, client_port, interface, pattern, listener, nil, sslctx ) | 701 local clientinterface = handleclient( client, client_ip, client_port, interface, pattern, listener, nil, sslctx ) |
| 700 --vdebug( "client id:", clientinterface, "startssl:", startssl ) | 702 --vdebug( "client id:", clientinterface, "startssl:", startssl ) |
| 701 if ssl and sslctx then | 703 if ssl and sslctx then |
| 702 clientinterface:starttls(sslctx) | 704 clientinterface:starttls(sslctx, true) |
| 703 else | 705 else |
| 704 clientinterface:_start_session( clientinterface.onconnect ) | 706 clientinterface:_start_session( true ) |
| 705 end | 707 end |
| 706 debug( "accepted incoming client connection from:", client_ip or "<unknown IP>", client_port or "<unknown port>", "to", port or "<unknown port>"); | 708 debug( "accepted incoming client connection from:", client_ip or "<unknown IP>", client_port or "<unknown port>", "to", port or "<unknown port>"); |
| 707 | 709 |
| 708 client, err = server:accept() -- try to accept again | 710 client, err = server:accept() -- try to accept again |
| 709 end | 711 end |
