Software /
code /
prosody
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 |
parent | 3387:ebb8d0f9a177 |
child | 3422: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 |