diff options
| author | Wilmer van der Gaast <wilmer@gaast.net> | 2012-11-11 23:32:47 +0000 | 
|---|---|---|
| committer | Wilmer van der Gaast <wilmer@gaast.net> | 2012-11-11 23:32:47 +0000 | 
| commit | e132b60e77f395463cf95dc4ee09e96e9658ae35 (patch) | |
| tree | 24a387ad64eaee17589b61cabaded508477b598f | |
| parent | dd672e2c4d0dcf73a30be3d8f7fc2ec38cb6450e (diff) | |
Extend keepalive code to time out connections when pings don't get
acknowledged, using this for Twitter streams and MSN so far.
| -rw-r--r-- | protocols/msn/msn.c | 1 | ||||
| -rw-r--r-- | protocols/msn/ns.c | 4 | ||||
| -rw-r--r-- | protocols/nogaim.c | 24 | ||||
| -rw-r--r-- | protocols/nogaim.h | 2 | ||||
| -rw-r--r-- | protocols/twitter/twitter.c | 1 | ||||
| -rw-r--r-- | protocols/twitter/twitter_lib.c | 1 | 
6 files changed, 31 insertions, 2 deletions
| diff --git a/protocols/msn/msn.c b/protocols/msn/msn.c index 71570ce0..845f9cf8 100644 --- a/protocols/msn/msn.c +++ b/protocols/msn/msn.c @@ -52,6 +52,7 @@ static void msn_login( account_t *acc )  	struct msn_data *md = g_new0( struct msn_data, 1 );  	ic->proto_data = md; +	ic->flags |= OPT_PONGS | OPT_PONGED;  	if( strchr( acc->user, '@' ) == NULL )  	{ diff --git a/protocols/msn/ns.c b/protocols/msn/ns.c index d9a558f9..7acf4654 100644 --- a/protocols/msn/ns.c +++ b/protocols/msn/ns.c @@ -576,6 +576,10 @@ static int msn_ns_command( struct msn_handler_data *handler, char **cmd, int num  		if( num_parts >= 7 )  			handler->msglen = atoi( cmd[6] );  	} +	else if( strcmp( cmd[0], "QNG" ) == 0 ) +	{ +		ic->flags |= OPT_PONGED; +	}  	else if( isdigit( cmd[0][0] ) )  	{  		int num = atoi( cmd[0] ); diff --git a/protocols/nogaim.c b/protocols/nogaim.c index 773e3877..744f73ad 100644 --- a/protocols/nogaim.c +++ b/protocols/nogaim.c @@ -260,12 +260,32 @@ static gboolean send_keepalive( gpointer d, gint fd, b_input_condition cond )  {  	struct im_connection *ic = d; +	if( ( ic->flags & OPT_PONGS ) && !( ic->flags & OPT_PONGED ) ) +	{ +		/* This protocol is expected to ack keepalives and hasn't +		   since the last time we were here. */ +		imcb_error( ic, "Connection timeout" ); +		imc_logout( ic, TRUE ); +		return FALSE; +	} +	ic->flags &= ~OPT_PONGED; +	  	if( ic->acc->prpl->keepalive )  		ic->acc->prpl->keepalive( ic );  	return TRUE;  } +void start_keepalives( struct im_connection *ic, int interval ) +{ +	b_event_remove( ic->keepalive ); +	ic->keepalive = b_timeout_add( interval, send_keepalive, ic ); +	 +	/* Connecting successfully counts as a first successful pong. */ +	if( ic->flags & OPT_PONGS ) +		ic->flags |= OPT_PONGED; +} +  void imcb_connected( struct im_connection *ic )  {  	/* MSN servers sometimes redirect you to a different server and do @@ -276,9 +296,9 @@ void imcb_connected( struct im_connection *ic )  	imcb_log( ic, "Logged in" ); -	b_event_remove( ic->keepalive ); -	ic->keepalive = b_timeout_add( 60000, send_keepalive, ic );  	ic->flags |= OPT_LOGGED_IN; +	if( !ic->keepalive ) +		start_keepalives( ic, 60000 );  	/* Necessary to send initial presence status, even if we're not away. */  	imc_away_send_update( ic ); diff --git a/protocols/nogaim.h b/protocols/nogaim.h index eccf77da..fb82fc73 100644 --- a/protocols/nogaim.h +++ b/protocols/nogaim.h @@ -67,6 +67,8 @@  #define OPT_TYPING      0x00000100 /* Some pieces of code make assumptions */  #define OPT_THINKING    0x00000200 /* about these values... Stupid me! */  #define OPT_NOOTR       0x00001000 /* protocol not suitable for OTR */ +#define OPT_PONGS       0x00010000 /* Service sends us keep-alives */ +#define OPT_PONGED      0x00020000 /* Received a keep-alive during last interval */  /* ok. now the fun begins. first we create a connection structure */  struct im_connection diff --git a/protocols/twitter/twitter.c b/protocols/twitter/twitter.c index f538f885..6bde497a 100644 --- a/protocols/twitter/twitter.c +++ b/protocols/twitter/twitter.c @@ -71,6 +71,7 @@ static void twitter_main_loop_start(struct im_connection *ic)  		/* That fetch was just to get backlog, the stream will give  		   us the rest. \o/ */  		twitter_open_stream(ic); +		ic->flags |= OPT_PONGS;  	} else {  		/* Not using the streaming API, so keep polling the old-  		   fashioned way. :-( */ diff --git a/protocols/twitter/twitter_lib.c b/protocols/twitter/twitter_lib.c index d7e54392..bf5d76ab 100644 --- a/protocols/twitter/twitter_lib.c +++ b/protocols/twitter/twitter_lib.c @@ -739,6 +739,7 @@ static void twitter_http_stream(struct http_request *req)  	if (!g_slist_find(twitter_connections, ic))  		return; +	ic->flags |= OPT_PONGED;  	td = ic->proto_data;  	if ((req->flags & HTTPC_EOF) || !req->reply_body) { | 
