@@ -29,6 +29,7 @@ enum state {
29
29
30
30
struct sip_strans {
31
31
struct le he ;
32
+ struct le he_mrg ;
32
33
struct tmr tmr ;
33
34
struct tmr tmrg ;
34
35
struct sa dst ;
@@ -48,6 +49,7 @@ static void destructor(void *arg)
48
49
struct sip_strans * st = arg ;
49
50
50
51
hash_unlink (& st -> he );
52
+ hash_unlink (& st -> he_mrg );
51
53
tmr_cancel (& st -> tmr );
52
54
tmr_cancel (& st -> tmrg );
53
55
mem_deref (st -> msg );
@@ -112,6 +114,30 @@ static bool cmp_cancel_handler(struct le *le, void *arg)
112
114
}
113
115
114
116
117
+ static bool cmp_merge_handler (struct le * le , void * arg )
118
+ {
119
+ struct sip_strans * st = le -> data ;
120
+ const struct sip_msg * msg = arg ;
121
+
122
+ if (pl_cmp (& st -> msg -> cseq .met , & msg -> cseq .met ))
123
+ return false;
124
+
125
+ if (st -> msg -> cseq .num != msg -> cseq .num )
126
+ return false;
127
+
128
+ if (pl_cmp (& st -> msg -> callid , & msg -> callid ))
129
+ return false;
130
+
131
+ if (pl_cmp (& st -> msg -> from .tag , & msg -> from .tag ))
132
+ return false;
133
+
134
+ if (pl_cmp (& st -> msg -> ruri , & msg -> ruri ))
135
+ return false;
136
+
137
+ return true;
138
+ }
139
+
140
+
115
141
static void dummy_handler (void * arg )
116
142
{
117
143
(void )arg ;
@@ -229,6 +255,16 @@ static bool request_handler(const struct sip_msg *msg, void *arg)
229
255
230
256
return true;
231
257
}
258
+ else if (!pl_isset (& msg -> to .tag )) {
259
+
260
+ st = list_ledata (hash_lookup (sip -> ht_strans_mrg ,
261
+ hash_joaat_pl (& msg -> callid ),
262
+ cmp_merge_handler , (void * )msg ));
263
+ if (st ) {
264
+ (void )sip_reply (sip , msg , 482 , "Loop Detected" );
265
+ return true;
266
+ }
267
+ }
232
268
233
269
if (!pl_strcmp (& msg -> met , "CANCEL" ))
234
270
return cancel_handler (sip , msg );
@@ -264,6 +300,9 @@ int sip_strans_alloc(struct sip_strans **stp, struct sip *sip,
264
300
hash_append (sip -> ht_strans , hash_joaat_pl (& msg -> via .branch ),
265
301
& st -> he , st );
266
302
303
+ hash_append (sip -> ht_strans_mrg , hash_joaat_pl (& msg -> callid ),
304
+ & st -> he_mrg , st );
305
+
267
306
st -> invite = !pl_strcmp (& msg -> met , "INVITE" );
268
307
st -> msg = mem_ref ((void * )msg );
269
308
st -> state = TRYING ;
@@ -367,6 +406,10 @@ int sip_strans_init(struct sip *sip, uint32_t sz)
367
406
if (err )
368
407
return err ;
369
408
409
+ err = hash_alloc (& sip -> ht_strans_mrg , sz );
410
+ if (err )
411
+ return err ;
412
+
370
413
return hash_alloc (& sip -> ht_strans , sz );
371
414
}
372
415
0 commit comments