Browse code

add some more support for transports other than UDP.

Raphael Coeffic authored on 29/04/2013 17:34:54
Showing 11 changed files
... ...
@@ -1089,6 +1089,7 @@ bool _RegisterCache::saveSingleContact(RegisterCacheCtx& ctx,
1089 1089
   alias_update.source_ip = req.remote_ip;
1090 1090
   alias_update.source_port = req.remote_port;
1091 1091
   alias_update.remote_ua = getHeader(req.hdrs,"User-Agent");
1092
+  alias_update.trsp = req.trsp;
1092 1093
   alias_update.local_if = req.local_if;
1093 1094
   alias_update.ua_expire = ua_expires + now.tv_sec;
1094 1095
 
... ...
@@ -56,6 +56,7 @@ struct AliasEntry
56 56
   // saved state for NAT handling
57 57
   string         source_ip;
58 58
   unsigned short source_port;
59
+  string         trsp;
59 60
 
60 61
   // sticky interface
61 62
   unsigned short local_if;
... ...
@@ -366,6 +366,7 @@ int RegisterDialog::initUAC(const AmSipRequest& req, const SBCCallProfile& cp)
366 366
     source_port = req.remote_port;
367 367
     local_if = req.local_if;
368 368
     from_ua = getHeader(req.hdrs,"User-Agent");
369
+    transport = req.trsp;
369 370
 
370 371
     min_reg_expire = cp.min_reg_expires;
371 372
     max_ua_expire = cp.max_ua_expires;
... ...
@@ -498,6 +499,7 @@ void RegisterDialog::onSipReply(const AmSipRequest& req,
498 499
 	alias_entry.source_ip   = source_ip;
499 500
 	alias_entry.source_port = source_port;
500 501
 	alias_entry.remote_ua   = from_ua;
502
+	alias_entry.trsp        = transport;
501 503
 	alias_entry.local_if    = local_if;
502 504
 	alias_entry.ua_expire   = orig_expires + now.tv_sec;
503 505
 
... ...
@@ -18,6 +18,7 @@ class RegisterDialog
18 18
   string         aor; // From-URI
19 19
   string         source_ip;
20 20
   unsigned short source_port;
21
+  string         transport;
21 22
   unsigned short local_if;
22 23
   string         from_ua;
23 24
 
... ...
@@ -41,6 +41,7 @@ class _AmSipMsgInDlg
41 41
   unsigned short remote_port;
42 42
   string         local_ip;
43 43
   unsigned short local_port;
44
+  string         trsp;
44 45
 
45 46
   _AmSipMsgInDlg() : cseq(0), rseq(0) { }
46 47
   virtual ~_AmSipMsgInDlg() { };
... ...
@@ -532,6 +532,7 @@ inline bool _SipCtrlInterface::sip_msg2am_request(const sip_msg *msg,
532 532
     req.local_ip = get_addr_str(&msg->local_ip).c_str();
533 533
     req.local_port = htons(((sockaddr_in*)&msg->local_ip)->sin_port);
534 534
 
535
+    req.trsp = msg->local_socket->get_transport();
535 536
     req.local_if = msg->local_socket->get_if();
536 537
 
537 538
     if(msg->vias.size() > 1) {
... ...
@@ -641,8 +642,8 @@ void _SipCtrlInterface::handle_sip_request(const trans_ticket& tt, sip_msg* msg)
641 642
     if(!sip_msg2am_request(msg, tt, req))
642 643
 	return;
643 644
 
644
-    DBG("Received new request from <%s:%i> on intf #%i\n",
645
-	req.remote_ip.c_str(),req.remote_port,req.local_if);
645
+    DBG("Received new request from <%s:%i/%s> on intf #%i\n",
646
+	req.remote_ip.c_str(),req.remote_port,req.trsp.c_str(),req.local_if);
646 647
 
647 648
     if (_SipCtrlInterface::log_parsed_messages) {
648 649
 	//     DBG_PARAM(req.cmd);
... ...
@@ -146,6 +146,10 @@ int parse_next_hop(const cstring& next_hop,
146 146
 	dest_list.push_back(dest);
147 147
 	break;
148 148
       default:
149
+	if( (*c >= 'a' && *c <= 'z') ||
150
+	    (*c >= 'A' && *c <= 'Z') ) {
151
+	  continue;
152
+	}
149 153
 	// syntax error
150 154
 	DBG("error: unexpected character '%c' in IPL_TRSP state.\n",*c);
151 155
 	return -1;
... ...
@@ -161,11 +165,17 @@ int parse_next_hop(const cstring& next_hop,
161 165
     break;
162 166
   case IPL_HOST:
163 167
     dest.host.set(beg,c-beg);
168
+    dest_list.push_back(dest);
169
+    break;
164 170
   case IPL_V6:
165 171
   case IPL_HOST_SEP:
166 172
   case IPL_PORT:
167 173
     dest_list.push_back(dest);
168 174
     break;
175
+  case IPL_TRSP:
176
+    dest.trsp.set(beg,c-beg);
177
+    dest_list.push_back(dest);
178
+    break;
169 179
   }
170 180
   
171 181
   return 0;
... ...
@@ -709,8 +709,10 @@ static void prepare_strict_routing(sip_msg* msg, string& ext_uri_buffer)
709 709
 //
710 710
 int _trans_layer::set_next_hop(sip_msg* msg, 
711 711
 			       cstring* next_hop,
712
-			       unsigned short* next_port)
712
+			       unsigned short* next_port,
713
+			       cstring* next_trsp)
713 714
 {
715
+    static const cstring default_trsp("udp");
714 716
     assert(msg);
715 717
 
716 718
     list<sip_header*>& route_hdrs = msg->route; 
... ...
@@ -730,6 +732,8 @@ int _trans_layer::set_next_hop(sip_msg* msg,
730 732
 	    *next_hop  = route_uri->host;
731 733
 	    if(route_uri->port_str.len)
732 734
 		*next_port = route_uri->port;
735
+	    if(route_uri->trsp->value.len)
736
+		*next_trsp = route_uri->trsp->value;
733 737
 	}
734 738
     }
735 739
     else {
... ...
@@ -742,12 +746,21 @@ int _trans_layer::set_next_hop(sip_msg* msg,
742 746
 	    ERROR("Invalid Request URI\n");
743 747
 	    return -1;
744 748
 	}
749
+	DBG("setting next-hop based on request-URI\n");
745 750
 	*next_hop  = parsed_r_uri.host;
746 751
 	if(parsed_r_uri.port_str.len)
747 752
 	    *next_port = parsed_r_uri.port;
753
+	if(parsed_r_uri.trsp)
754
+	    *next_trsp = parsed_r_uri.trsp->value;
748 755
     }
749 756
 
750
-    DBG("next_hop:next_port is <%.*s:%u>\n", next_hop->len, next_hop->s, *next_port);
757
+    if(!next_trsp->len)
758
+	*next_trsp = default_trsp;
759
+
760
+    DBG("next_hop:next_port is <%.*s:%u/%.*s>\n",
761
+	next_hop->len, next_hop->s, *next_port,
762
+	next_trsp ? next_trsp->len : 0,
763
+	next_trsp ? next_trsp->s : 0);
751 764
     
752 765
     return 0;
753 766
 }
... ...
@@ -883,6 +896,7 @@ int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt,
883 896
 
884 897
     cstring next_hop;
885 898
     unsigned short next_port=0;
899
+    cstring next_trsp;
886 900
 
887 901
     int res=0;
888 902
     if (_next_hop.len) {
... ...
@@ -895,8 +909,13 @@ int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt,
895 909
 	}
896 910
 
897 911
 	if(dest_list.size() == 1) {
898
-	    next_hop = dest_list.front().host;
899
-	    next_port = dest_list.front().port ? dest_list.front().port : 5060;
912
+	    const sip_destination& dest = dest_list.front();
913
+	    next_hop = dest.host;
914
+	    next_port = dest.port ? dest.port : 5060;
915
+	    next_trsp = dest.trsp;
916
+	    DBG("single next-hop: <%.*s:%u/%.*s>",
917
+		next_hop.len,next_hop.s,next_port,
918
+		next_trsp.len,next_trsp.s);
900 919
 	}
901 920
 	else if(dest_list.size() > 1) {
902 921
 	    dns_ip_entry* e = new dns_ip_entry();
... ...
@@ -906,12 +925,13 @@ int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt,
906 925
 	    }
907 926
 
908 927
 	    inc_ref(e);
928
+	    //TODO: avoid to loose the transport from the next-hop-list
909 929
 	    e->next_ip(&msg->h_dns,&msg->remote_ip);
910 930
 	    DBG("destination set to <%s>\n",get_addr_str(&msg->remote_ip).c_str());
911 931
 	}
912 932
     }
913 933
     else {
914
-	if(set_next_hop(msg,&next_hop,&next_port) < 0){
934
+	if(set_next_hop(msg,&next_hop,&next_port,&next_trsp) < 0){
915 935
 	    DBG("set_next_hop failed\n");
916 936
 	    return -1;
917 937
 	}
... ...
@@ -1679,24 +1699,36 @@ int _trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_ms
1679 1699
 	return 0;
1680 1700
     }
1681 1701
 
1702
+    DBG("transport = '%s'; is_reliable = %i",
1703
+	msg->local_socket->get_transport(),
1704
+	msg->local_socket->is_reliable());
1705
+
1682 1706
     switch(msg->u.request->method){
1683 1707
 
1684 1708
     case sip_request::INVITE:
1685
-	// if transport == UDP
1686
-	t->reset_timer(STIMER_A,A_TIMER,bucket->get_id());
1687
-	// for any transport type
1688
-	t->reset_timer(STIMER_B,B_TIMER,bucket->get_id());
1709
+	if(!msg->local_socket->is_reliable()) {
1710
+	    // if transport == UDP
1711
+	    t->reset_timer(STIMER_A,A_TIMER,bucket->get_id());
1712
+	}
1713
+	else {
1714
+	    // for any transport type
1715
+	    t->reset_timer(STIMER_B,B_TIMER,bucket->get_id());
1716
+	}
1689 1717
 	break;
1690 1718
     
1691 1719
     default:
1692
-	// if transport == UDP
1693
-	t->reset_timer(STIMER_E,E_TIMER,bucket->get_id());
1694
-	// for any transport type
1695
-	t->reset_timer(STIMER_F,F_TIMER,bucket->get_id());
1720
+	if(!msg->local_socket->is_reliable()) {
1721
+	    // if transport == UDP
1722
+	    t->reset_timer(STIMER_E,E_TIMER,bucket->get_id());
1723
+	}
1724
+	else {
1725
+	    // for any transport type
1726
+	    t->reset_timer(STIMER_F,F_TIMER,bucket->get_id());
1727
+	}
1696 1728
 	break;
1697 1729
     }
1698 1730
 
1699
-    if(!msg->h_dns.eoip()){ // if transport == UDP
1731
+    if(!msg->h_dns.eoip()){
1700 1732
 	t->reset_timer(STIMER_M,M_TIMER,bucket->get_id());
1701 1733
     }
1702 1734
 
... ...
@@ -2140,9 +2172,11 @@ int _trans_layer::try_next_ip(trans_bucket* bucket, sip_trans* tr)
2140 2172
 			tr->msg->u.request->method_str);
2141 2173
     }
2142 2174
 
2143
-    // reset counter for timer A & E
2144
-    trans_timer* A_E_timer = tr->get_timer(STIMER_A);
2145
-    tr->reset_timer(A_E_timer->type & 0xFFFF,A_TIMER,bucket->get_id());
2175
+    if(!tr->msg->local_socket->is_reliable()) {
2176
+	// reset counter for timer A & E
2177
+	trans_timer* A_E_timer = tr->get_timer(STIMER_A);
2178
+	tr->reset_timer(A_E_timer->type & 0xFFFF,A_TIMER,bucket->get_id());
2179
+    }
2146 2180
     
2147 2181
     if(!tr->msg->h_dns.eoip())
2148 2182
 	tr->reset_timer(STIMER_M,M_TIMER,bucket->get_id());
... ...
@@ -175,8 +175,10 @@ protected:
175 175
      * Fills the address structure passed and modifies 
176 176
      * R-URI and Route headers as needed.
177 177
      */
178
-    int set_next_hop(sip_msg* msg, cstring* next_hop,
179
-		     unsigned short* next_port);
178
+    int set_next_hop(sip_msg* msg,
179
+		     cstring* next_hop,
180
+		     unsigned short* next_port,
181
+		     cstring* next_trsp);
180 182
 
181 183
     /**
182 184
      * Fills msg->remote_ip according to next_hop and next_port.
... ...
@@ -80,6 +80,11 @@ public:
80 80
      */
81 81
     virtual int bind(const string& address, unsigned short port)=0;
82 82
 
83
+    /**
84
+     * Getter for the transport name
85
+     */
86
+    virtual const char* get_transport() const = 0;
87
+
83 88
     /**
84 89
      * Getter for IP address
85 90
      */
... ...
@@ -60,6 +60,9 @@ public:
60 60
      */
61 61
     virtual int bind(const string& address, unsigned short port);
62 62
 
63
+    const char* get_transport() const
64
+    { return "udp"; }
65
+
63 66
     int set_recvbuf_size(int rcvbuf_size);
64 67
 
65 68
     /**