5050#include "ua_api.h"
5151
5252#define BUF_LEN 65535
53+ #define RACK_HDR_PREFIX "RAck: "
54+ #define RACK_HDR_PREFIX_LEN (sizeof(RACK_HDR_PREFIX) - 1)
5355
5456str ack = str_init (ACK );
5557str bye = str_init (BYE );
@@ -3608,8 +3610,9 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps)
36083610 {
36093611 str method = {"PRACK" , 5 };
36103612 str extra_headers ;
3611- char buf [128 ];
36123613 str rseq , cseq ;
3614+ char * p ;
3615+ int rack_overhead ;
36133616 hdr = get_header_by_static_name ( msg , "RSeq" );
36143617 if (!hdr )
36153618 {
@@ -3620,20 +3623,46 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps)
36203623 cseq = msg -> cseq -> body ;
36213624 trim_trailing (& rseq );
36223625 trim_trailing (& cseq );
3623- sprintf (buf , "RAck: %.*s %.*s\r\n" ,
3624- rseq .len , rseq .s , cseq .len , cseq .s );
3625- extra_headers .s = buf ;
3626- extra_headers .len = strlen (buf );
3626+ rack_overhead = RACK_HDR_PREFIX_LEN + 1 /* space */ + CRLF_LEN ;
3627+ if (rseq .len < 0 || cseq .len < 0 ||
3628+ rseq .len > BUF_LEN - rack_overhead ||
3629+ cseq .len > BUF_LEN - rack_overhead - rseq .len ) {
3630+ LM_ERR ("RAck header too large\n" );
3631+ goto error ;
3632+ }
3633+ extra_headers .len = rack_overhead + rseq .len + cseq .len ;
3634+ extra_headers .s = pkg_malloc (extra_headers .len );
3635+ if (!extra_headers .s ) {
3636+ LM_ERR ("no more private memory\n" );
3637+ goto error ;
3638+ }
3639+
3640+ p = extra_headers .s ;
3641+ memcpy (p , RACK_HDR_PREFIX , RACK_HDR_PREFIX_LEN );
3642+ p += RACK_HDR_PREFIX_LEN ;
3643+ memcpy (p , rseq .s , rseq .len );
3644+ p += rseq .len ;
3645+ * p ++ = ' ' ;
3646+ memcpy (p , cseq .s , cseq .len );
3647+ p += cseq .len ;
3648+ memcpy (p , CRLF , CRLF_LEN );
36273649 if (passthru_prack )
36283650 {
36293651 /* Store the RAck header for when a response PRACK comes */
36303652 if (dlg -> prack_headers .s ) {
36313653 shm_free (dlg -> prack_headers .s );
3654+ dlg -> prack_headers .s = NULL ;
3655+ dlg -> prack_headers .len = 0 ;
36323656 }
36333657 dlg -> prack_headers .s = shm_malloc (extra_headers .len );
3658+ if (!dlg -> prack_headers .s ) {
3659+ LM_ERR ("no more shared memory\n" );
3660+ pkg_free (extra_headers .s );
3661+ goto error ;
3662+ }
36343663 memcpy (dlg -> prack_headers .s , extra_headers .s , extra_headers .len );
36353664 dlg -> prack_headers .len = extra_headers .len ;
3636- LM_ERR ("dlg->prack_headers %d[%.*s]\n" , dlg -> prack_headers .len ,dlg -> prack_headers .len , dlg -> prack_headers .s );
3665+ LM_DBG ("dlg->prack_headers %d[%.*s]\n" , dlg -> prack_headers .len ,dlg -> prack_headers .len , dlg -> prack_headers .s );
36373666 }
36383667 else
36393668 {
@@ -3645,6 +3674,7 @@ void b2b_tm_cback(struct cell *t, b2b_table htable, struct tmcb_params *ps)
36453674 LM_ERR ("Failed to send PRACK\n" );
36463675 }
36473676 }
3677+ pkg_free (extra_headers .s );
36483678 }
36493679 goto done ;
36503680 }
0 commit comments