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,7 @@ 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 ) * len = l ;
13281346 return 0 ;
13291347}
13301348
@@ -1454,10 +1472,17 @@ int xmpp_conn_restore_sm_state(xmpp_conn_t *conn,
14541472 ret = sm_load_string (& sm , & item -> data , & item -> len );
14551473 if (ret )
14561474 goto err_reload ;
1475+ if (sm .state < sm .state_end ) {
1476+ ret = sm_load_string (& sm , & item -> id , NULL );
1477+ if (ret )
1478+ goto err_reload ;
1479+ }
14571480
14581481 item -> owner = XMPP_QUEUE_USER ;
14591482 }
14601483
1484+ assert (sm .state == sm .state_end );
1485+
14611486 return XMPP_EOK ;
14621487
14631488err_reload :
@@ -1563,6 +1588,17 @@ static size_t sm_state_serialize(xmpp_conn_t *conn, unsigned char **buf)
15631588 goto err_serialize ;
15641589 memcpy (next , peek -> data , peek -> len );
15651590 next += peek -> len ;
1591+
1592+ if (peek -> id ) {
1593+ uint32_t len = strlen (peek -> id );
1594+ if (sm_store_u32 (& next , end , 0x7a , len ))
1595+ goto err_serialize ;
1596+ if (next + len > end )
1597+ goto err_serialize ;
1598+ memcpy (next , peek -> id , len );
1599+ next += len ;
1600+ }
1601+
15661602 peek = peek -> next ;
15671603 }
15681604
@@ -1813,6 +1849,10 @@ char *xmpp_conn_send_queue_drop_element(xmpp_conn_t *conn,
18131849 if (!t )
18141850 return NULL ;
18151851
1852+ if (conn -> sm_ack_callback && t -> id ) {
1853+ conn -> sm_ack_callback (conn , conn -> sm_ack_callback_ctx , t -> id );
1854+ }
1855+
18161856 /* In case there exists a SM stanza that is linked to the
18171857 * one we're currently dropping, also delete that one.
18181858 */
@@ -2088,6 +2128,9 @@ static void _conn_sm_handle_stanza(xmpp_conn_t *const conn,
20882128 e = pop_queue_front (& conn -> sm_state -> sm_queue );
20892129 strophe_debug_verbose (2 , conn -> ctx , "conn" ,
20902130 "SM_Q_DROP: %p, h=%lu" , e , e -> sm_h );
2131+ if (conn -> sm_ack_callback && e -> id ) {
2132+ conn -> sm_ack_callback (conn , conn -> sm_ack_callback_ctx , e -> id );
2133+ }
20912134 c = queue_element_free (conn -> ctx , e );
20922135 strophe_free (conn -> ctx , c );
20932136 }
@@ -2115,6 +2158,7 @@ char *queue_element_free(xmpp_ctx_t *ctx, xmpp_send_queue_t *e)
21152158{
21162159 char * ret = e -> data ;
21172160 strophe_debug_verbose (2 , ctx , "conn" , "Q_FREE: %p" , e );
2161+ strophe_free (ctx , e -> id );
21182162 memset (e , 0 , sizeof (* e ));
21192163 strophe_free (ctx , e );
21202164 strophe_debug_verbose (3 , ctx , "conn" , "Q_CONTENT: %s" , ret );
@@ -2231,7 +2275,7 @@ void send_raw(xmpp_conn_t *conn,
22312275 return ;
22322276 }
22332277
2234- _send_raw (conn , d , len , owner , userdata );
2278+ _send_raw (conn , d , len , NULL , owner , userdata );
22352279}
22362280
22372281static void _send_valist (xmpp_conn_t * conn ,
@@ -2266,7 +2310,7 @@ static void _send_valist(xmpp_conn_t *conn,
22662310 va_end (apdup );
22672311
22682312 /* len - 1 so we don't send trailing \0 */
2269- _send_raw (conn , bigbuf , len - 1 , owner , NULL );
2313+ _send_raw (conn , bigbuf , len - 1 , NULL , owner , NULL );
22702314 } else {
22712315 /* go through send_raw() which does the strdup() for us */
22722316 send_raw (conn , buf , len , owner , NULL );
@@ -2300,7 +2344,7 @@ void send_stanza(xmpp_conn_t *conn,
23002344 goto out ;
23012345 }
23022346
2303- _send_raw (conn , buf , len , owner , NULL );
2347+ _send_raw (conn , buf , len , xmpp_stanza_get_attribute ( stanza , "id" ), owner , NULL );
23042348out :
23052349 xmpp_stanza_release (stanza );
23062350}
@@ -2342,6 +2386,7 @@ xmpp_send_queue_t *pop_queue_front(xmpp_queue_t *queue)
23422386static int _send_raw (xmpp_conn_t * conn ,
23432387 char * data ,
23442388 size_t len ,
2389+ const char * id ,
23452390 xmpp_send_queue_owner_t owner ,
23462391 void * userdata )
23472392{
@@ -2358,6 +2403,7 @@ static int _send_raw(xmpp_conn_t *conn,
23582403
23592404 item -> data = data ;
23602405 item -> len = len ;
2406+ item -> id = id ? strophe_strdup (conn -> ctx , id ) : NULL ;
23612407 item -> next = NULL ;
23622408 item -> prev = conn -> send_queue_tail ;
23632409 item -> written = 0 ;
0 commit comments