comparison libpurple/protocols/jabber/bosh.c @ 27802:20f13609ca7a

jabber: Keep a second connection open over which to send the terminate.
author Paul Aurich <paul@darkrain42.org>
date Sun, 02 Aug 2009 20:42:00 +0000
parents 3eef8392a54b
children c585572e80dd
comparison
equal deleted inserted replaced
27801:5b21007cf503 27802:20f13609ca7a
27 #include "util.h" 27 #include "util.h"
28 #include "xmlnode.h" 28 #include "xmlnode.h"
29 29
30 #include "bosh.h" 30 #include "bosh.h"
31 31
32 #define MAX_HTTP_CONNECTIONS 2 32 /* The number of HTTP connections to use. This MUST be at least 2. */
33 #define NUM_HTTP_CONNECTIONS 2
34 /* How many failed connection attempts before it becomes a fatal error */
33 #define MAX_FAILED_CONNECTIONS 3 35 #define MAX_FAILED_CONNECTIONS 3
36 /* How long in seconds to queue up outgoing messages */
34 #define BUFFER_SEND_IN_SECS 1 37 #define BUFFER_SEND_IN_SECS 1
35 38
36 typedef struct _PurpleHTTPConnection PurpleHTTPConnection; 39 typedef struct _PurpleHTTPConnection PurpleHTTPConnection;
37 40
38 typedef void (*PurpleBOSHConnectionConnectFunction)(PurpleBOSHConnection *conn); 41 typedef void (*PurpleBOSHConnectionConnectFunction)(PurpleBOSHConnection *conn);
46 PACKET_FLUSH, 49 PACKET_FLUSH,
47 } PurpleBOSHPacketType; 50 } PurpleBOSHPacketType;
48 51
49 struct _PurpleBOSHConnection { 52 struct _PurpleBOSHConnection {
50 JabberStream *js; 53 JabberStream *js;
51 PurpleHTTPConnection *connections[MAX_HTTP_CONNECTIONS]; 54 PurpleHTTPConnection *connections[NUM_HTTP_CONNECTIONS];
52 55
53 PurpleCircBuffer *pending; 56 PurpleCircBuffer *pending;
54 PurpleBOSHConnectionConnectFunction connect_cb; 57 PurpleBOSHConnectionConnectFunction connect_cb;
55 PurpleBOSHConnectionReceiveFunction receive_cb; 58 PurpleBOSHConnectionReceiveFunction receive_cb;
56 59
239 if (conn->inactivity_timer) 242 if (conn->inactivity_timer)
240 purple_timeout_remove(conn->inactivity_timer); 243 purple_timeout_remove(conn->inactivity_timer);
241 244
242 purple_circ_buffer_destroy(conn->pending); 245 purple_circ_buffer_destroy(conn->pending);
243 246
244 for (i = 0; i < MAX_HTTP_CONNECTIONS; ++i) { 247 for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
245 if (conn->connections[i]) 248 if (conn->connections[i])
246 jabber_bosh_http_connection_destroy(conn->connections[i]); 249 jabber_bosh_http_connection_destroy(conn->connections[i]);
247 } 250 }
248 251
249 g_free(conn); 252 g_free(conn);
258 find_available_http_connection(PurpleBOSHConnection *conn) 261 find_available_http_connection(PurpleBOSHConnection *conn)
259 { 262 {
260 int i; 263 int i;
261 264
262 if (purple_debug_is_verbose()) { 265 if (purple_debug_is_verbose()) {
263 for (i = 0; i < MAX_HTTP_CONNECTIONS; ++i) { 266 for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
264 PurpleHTTPConnection *httpconn = conn->connections[i]; 267 PurpleHTTPConnection *httpconn = conn->connections[i];
265 if (httpconn == NULL) 268 if (httpconn == NULL)
266 purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n", 269 purple_debug_misc("jabber", "BOSH %p->connections[%d] = (nil)\n",
267 conn, i); 270 conn, i);
268 else 271 else
277 if (conn->pipelining) 280 if (conn->pipelining)
278 return conn->connections[0]->state == HTTP_CONN_CONNECTED ? 281 return conn->connections[0]->state == HTTP_CONN_CONNECTED ?
279 conn->connections[0] : NULL; 282 conn->connections[0] : NULL;
280 283
281 /* First loop, look for a connection that's ready */ 284 /* First loop, look for a connection that's ready */
282 for (i = 0; i < MAX_HTTP_CONNECTIONS; ++i) { 285 for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
283 if (conn->connections[i] && 286 if (conn->connections[i] &&
284 conn->connections[i]->state == HTTP_CONN_CONNECTED && 287 conn->connections[i]->state == HTTP_CONN_CONNECTED &&
285 conn->connections[i]->requests == 0) 288 conn->connections[i]->requests == 0)
286 return conn->connections[i]; 289 return conn->connections[i];
287 } 290 }
288 291
289 /* Second loop, is something currently connecting? If so, just queue up. */ 292 /* Second loop, is something currently connecting? If so, just queue up. */
290 for (i = 0; i < MAX_HTTP_CONNECTIONS; ++i) { 293 for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
291 if (conn->connections[i] && 294 if (conn->connections[i] &&
292 conn->connections[i]->state == HTTP_CONN_CONNECTING) 295 conn->connections[i]->state == HTTP_CONN_CONNECTING)
293 return NULL; 296 return NULL;
294 } 297 }
295 298
296 /* Third loop, look for one that's NULL and create a new connection */ 299 /* Third loop, look for one that's NULL and create a new connection */
297 for (i = 0; i < MAX_HTTP_CONNECTIONS; ++i) { 300 for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
298 if (!conn->connections[i]) { 301 if (!conn->connections[i]) {
299 purple_debug_info("jabber", "bosh: Creating and connecting new httpconn\n"); 302 purple_debug_info("jabber", "bosh: Creating and connecting new httpconn\n");
300 conn->connections[i] = jabber_bosh_http_connection_init(conn); 303 conn->connections[i] = jabber_bosh_http_connection_init(conn);
301 304
302 http_connection_connect(conn->connections[i]); 305 http_connection_connect(conn->connections[i]);
699 purple_debug_error("jabber", "bosh: Adjusting BOSHconn requests (%d) to %d\n", 702 purple_debug_error("jabber", "bosh: Adjusting BOSHconn requests (%d) to %d\n",
700 conn->bosh->requests, conn->bosh->requests - conn->requests); 703 conn->bosh->requests, conn->bosh->requests - conn->requests);
701 conn->bosh->requests -= conn->requests; 704 conn->bosh->requests -= conn->requests;
702 conn->requests = 0; 705 conn->requests = 0;
703 } 706 }
704 if (conn->bosh->pipelining) 707
708 if (conn->bosh->pipelining) {
705 /* Hmmmm, fall back to multiple connections */ 709 /* Hmmmm, fall back to multiple connections */
706 conn->bosh->pipelining = FALSE; 710 conn->bosh->pipelining = FALSE;
711 if (conn->bosh->connections[1] == NULL) {
712 conn->bosh->connections[1] = jabber_bosh_http_connection_init(conn->bosh);
713 http_connection_connect(conn->bosh->connections[1]);
714 }
715 }
707 716
708 if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) { 717 if (++conn->bosh->failed_connections == MAX_FAILED_CONNECTIONS) {
709 purple_connection_error_reason(conn->bosh->js->gc, 718 purple_connection_error_reason(conn->bosh->js->gc,
710 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 719 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
711 _("Unable to establish a connection with the server")); 720 _("Unable to establish a connection with the server"));