Browse Source

Currently, SER matches E2E ACKs only if there is an equality between From HF
in INVITE and ACK. While this is pretty safe, there are UAs that do mess small
things, like display name, or some bigger ones, like URI, in generated ACK.
However, matching over the full URI (or worse, HF) is not needed and was even
intended for deprecation (see 1st comment of 3261#Sec. 12.2.1.1).
The applied patch should boost a bit the matching flexibility - only compare
the tag.

Closes #SER-419.

Bogdan Pintea 16 years ago
parent
commit
eddf3e3b7b
2 changed files with 25 additions and 3 deletions
  1. 4 1
      NEWS
  2. 21 2
      modules/tm/t_lookup.c

+ 4 - 1
NEWS

@@ -77,7 +77,10 @@ modules:
  - blst      - new module containing script blacklist manipulations functions
                (the source of a message can be blacklisted, removed from the
                 blacklist or checked for presence in the blacklist).
- - tm        - added t_reset_fr(), t_reset_retr(), t_reset_max_lifetime()
+ - tm        - matching of E2E ACKs no longer requires full From HF identity,
+               but rather only tag equality (this behaviour can be changed by
+               defining TM_E2E_ACK_CHECK_FROM_URI)
+             - added t_reset_fr(), t_reset_retr(), t_reset_max_lifetime()
              - t_relay_to renamed to t_relay_to_avp (undocumented function)
              - t_relay() can now also take host and port parameters (e.g.
                t_relay(host, port)), behaving like a statefull 

+ 21 - 2
modules/tm/t_lookup.c

@@ -605,19 +605,34 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked,
 			/* CSeq only the number without method ! */
 			if (get_cseq(t_msg)->number.len!=get_cseq(p_msg)->number.len)
 				continue;
-			if (! EQ_LEN(from)) continue;
 			/* To only the uri -- to many UACs screw up tags  */
 			if (get_to(t_msg)->uri.len!=get_to(p_msg)->uri.len)
 				continue;
 			if (!EQ_STR(callid)) continue;
 			if (memcmp(get_cseq(t_msg)->number.s, get_cseq(p_msg)->number.s,
 				get_cseq(p_msg)->number.len)!=0) continue;
-			if (!EQ_STR(from)) continue;
 			if (memcmp(get_to(t_msg)->uri.s, get_to(p_msg)->uri.s,
 				get_to(t_msg)->uri.len)!=0) continue;
 			
 			/* it is e2e ACK/200 */
 			if (p_cell->uas.status<300) {
+				/* For e2e ACKs, From's tag 'MUST' equal INVITE's, while use
+				 * of the URI in this case is to be deprecated (Sec. 12.2.1.1).
+				 * Comparing entire From body is dangerous, since some UAs
+				 * screw the display name up. */
+				if (parse_from_header(p_msg) < 0) {
+					ERR("failed to parse From HF; ACK might not match.\n");
+					continue;
+				}
+				if (! STR_EQ(get_from(t_msg)->tag_value, 
+						get_from(p_msg)->tag_value))
+					continue;
+#ifdef TM_E2E_ACK_CHECK_FROM_URI
+				if (! STR_EQ(get_from(t_msg)->uri, 
+						get_from(p_msg)->uri))
+					continue;
+#endif
+
 				/* all criteria for proxied ACK are ok */
 				if (likely(p_cell->relayed_reply_branch!=-2)) {
 					if (unlikely(has_tran_tmcbs(p_cell, 
@@ -633,6 +648,10 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked,
 				if (dlg_matching(p_cell, p_msg))
 					goto found;
 				continue;
+			} else {
+				/* for hbh ACKs, From HF 'MUST' equal INVITE's one */
+				if (! EQ_LEN(from)) continue;
+				if (! EQ_STR(from)) continue;
 			}
 			
 			/* it is not an e2e ACK/200 -- perhaps it is