2020 * A part of those functions is listed under the \ref TLS section.
2121 */
2222
23+ #include <assert.h>
2324#include <errno.h>
2425#include <netinet/in.h>
2526#include <stdarg.h>
@@ -115,6 +116,7 @@ static void _send_valist(xmpp_conn_t *conn,
115116static int _send_raw (xmpp_conn_t * conn ,
116117 char * data ,
117118 size_t len ,
119+ const char * id ,
118120 xmpp_send_queue_owner_t owner ,
119121 void * userdata );
120122
@@ -1279,6 +1281,22 @@ void xmpp_conn_set_sm_callback(xmpp_conn_t *conn,
12791281 conn -> sm_callback_ctx = ctx ;
12801282}
12811283
1284+ void xmpp_conn_set_sm_ack_callback (xmpp_conn_t * conn ,
1285+ xmpp_sm_ack_callback cb ,
1286+ void * ctx )
1287+ {
1288+ conn -> sm_ack_callback = cb ;
1289+ conn -> sm_ack_callback_ctx = ctx ;
1290+ }
1291+
1292+ void xmpp_conn_set_sm_fail_callback (xmpp_conn_t * conn ,
1293+ xmpp_sm_ack_callback cb ,
1294+ void * ctx )
1295+ {
1296+ conn -> sm_fail_callback = cb ;
1297+ conn -> sm_fail_callback_ctx = ctx ;
1298+ }
1299+
12821300struct sm_restore {
12831301 xmpp_conn_t * conn ;
12841302 const unsigned char * state ;
@@ -1324,7 +1342,8 @@ static int sm_load_string(struct sm_restore *sm, char **val, size_t *len)
13241342 memcpy (* val , sm -> state , l );
13251343 (* val )[l ] = '\0' ;
13261344 sm -> state += l ;
1327- * len = l ;
1345+ if (len )
1346+ * len = l ;
13281347 return 0 ;
13291348}
13301349
@@ -1454,10 +1473,17 @@ int xmpp_conn_restore_sm_state(xmpp_conn_t *conn,
14541473 ret = sm_load_string (& sm , & item -> data , & item -> len );
14551474 if (ret )
14561475 goto err_reload ;
1476+ if (sm .state < sm .state_end ) {
1477+ ret = sm_load_string (& sm , & item -> id , NULL );
1478+ if (ret )
1479+ goto err_reload ;
1480+ }
14571481
14581482 item -> owner = XMPP_QUEUE_USER ;
14591483 }
14601484
1485+ assert (sm .state == sm .state_end );
1486+
14611487 return XMPP_EOK ;
14621488
14631489err_reload :
@@ -1563,6 +1589,17 @@ static size_t sm_state_serialize(xmpp_conn_t *conn, unsigned char **buf)
15631589 goto err_serialize ;
15641590 memcpy (next , peek -> data , peek -> len );
15651591 next += peek -> len ;
1592+
1593+ if (peek -> id ) {
1594+ uint32_t len = strlen (peek -> id );
1595+ if (sm_store_u32 (& next , end , 0x7a , len ))
1596+ goto err_serialize ;
1597+ if (next + len > end )
1598+ goto err_serialize ;
1599+ memcpy (next , peek -> id , len );
1600+ next += len ;
1601+ }
1602+
15661603 peek = peek -> next ;
15671604 }
15681605
@@ -1813,6 +1850,10 @@ char *xmpp_conn_send_queue_drop_element(xmpp_conn_t *conn,
18131850 if (!t )
18141851 return NULL ;
18151852
1853+ if (conn -> sm_ack_callback && t -> id ) {
1854+ conn -> sm_ack_callback (conn , conn -> sm_ack_callback_ctx , t -> id );
1855+ }
1856+
18161857 /* In case there exists a SM stanza that is linked to the
18171858 * one we're currently dropping, also delete that one.
18181859 */
@@ -2088,6 +2129,10 @@ static void _conn_sm_handle_stanza(xmpp_conn_t *const conn,
20882129 e = pop_queue_front (& conn -> sm_state -> sm_queue );
20892130 strophe_debug_verbose (2 , conn -> ctx , "conn" ,
20902131 "SM_Q_DROP: %p, h=%lu" , e , e -> sm_h );
2132+ if (conn -> sm_ack_callback && e -> id ) {
2133+ conn -> sm_ack_callback (conn , conn -> sm_ack_callback_ctx ,
2134+ e -> id );
2135+ }
20912136 c = queue_element_free (conn -> ctx , e );
20922137 strophe_free (conn -> ctx , c );
20932138 }
@@ -2115,6 +2160,7 @@ char *queue_element_free(xmpp_ctx_t *ctx, xmpp_send_queue_t *e)
21152160{
21162161 char * ret = e -> data ;
21172162 strophe_debug_verbose (2 , ctx , "conn" , "Q_FREE: %p" , e );
2163+ strophe_free (ctx , e -> id );
21182164 memset (e , 0 , sizeof (* e ));
21192165 strophe_free (ctx , e );
21202166 strophe_debug_verbose (3 , ctx , "conn" , "Q_CONTENT: %s" , ret );
@@ -2231,7 +2277,7 @@ void send_raw(xmpp_conn_t *conn,
22312277 return ;
22322278 }
22332279
2234- _send_raw (conn , d , len , owner , userdata );
2280+ _send_raw (conn , d , len , NULL , owner , userdata );
22352281}
22362282
22372283static void _send_valist (xmpp_conn_t * conn ,
@@ -2266,7 +2312,7 @@ static void _send_valist(xmpp_conn_t *conn,
22662312 va_end (apdup );
22672313
22682314 /* len - 1 so we don't send trailing \0 */
2269- _send_raw (conn , bigbuf , len - 1 , owner , NULL );
2315+ _send_raw (conn , bigbuf , len - 1 , NULL , owner , NULL );
22702316 } else {
22712317 /* go through send_raw() which does the strdup() for us */
22722318 send_raw (conn , buf , len , owner , NULL );
@@ -2300,7 +2346,8 @@ void send_stanza(xmpp_conn_t *conn,
23002346 goto out ;
23012347 }
23022348
2303- _send_raw (conn , buf , len , owner , NULL );
2349+ _send_raw (conn , buf , len , xmpp_stanza_get_attribute (stanza , "id" ), owner ,
2350+ NULL );
23042351out :
23052352 xmpp_stanza_release (stanza );
23062353}
@@ -2342,6 +2389,7 @@ xmpp_send_queue_t *pop_queue_front(xmpp_queue_t *queue)
23422389static int _send_raw (xmpp_conn_t * conn ,
23432390 char * data ,
23442391 size_t len ,
2392+ const char * id ,
23452393 xmpp_send_queue_owner_t owner ,
23462394 void * userdata )
23472395{
@@ -2358,6 +2406,7 @@ static int _send_raw(xmpp_conn_t *conn,
23582406
23592407 item -> data = data ;
23602408 item -> len = len ;
2409+ item -> id = id ? strophe_strdup (conn -> ctx , id ) : NULL ;
23612410 item -> next = NULL ;
23622411 item -> prev = conn -> send_queue_tail ;
23632412 item -> written = 0 ;
0 commit comments