This allows, among other things, to keep the transport set in the next-hop list and remove the use of fake DNS records.
... | ... |
@@ -95,7 +95,8 @@ int dns_ip_entry::next_ip(dns_handle* h, sockaddr_storage* sa) |
95 | 95 |
} |
96 | 96 |
|
97 | 97 |
int& index = h->ip_n; |
98 |
- if(index >= (int)ip_vec.size()) return -1; |
|
98 |
+ if((index < 0) || (index >= (int)ip_vec.size())) |
|
99 |
+ return -1; |
|
99 | 100 |
|
100 | 101 |
//copy address |
101 | 102 |
((ip_entry*)ip_vec[index++])->to_sa(sa); |
... | ... |
@@ -176,8 +177,6 @@ public: |
176 | 177 |
int next_ip(dns_handle* h, sockaddr_storage* sa) |
177 | 178 |
{ |
178 | 179 |
int& index = h->srv_n; |
179 |
- if(index >= (int)ip_vec.size()) return -1; |
|
180 |
- |
|
181 | 180 |
if(h->srv_e != this){ |
182 | 181 |
if(h->srv_e) dec_ref(h->srv_e); |
183 | 182 |
h->srv_e = this; |
... | ... |
@@ -195,6 +194,10 @@ public: |
195 | 194 |
} |
196 | 195 |
return h->ip_e->next_ip(h,sa); |
197 | 196 |
} |
197 |
+ |
|
198 |
+ if((index < 0) || |
|
199 |
+ (index >= (int)ip_vec.size())) |
|
200 |
+ return -1; |
|
198 | 201 |
|
199 | 202 |
// reset IP record |
200 | 203 |
if(h->ip_e){ |
... | ... |
@@ -35,6 +35,7 @@ |
35 | 35 |
#include "trans_layer.h" |
36 | 36 |
#include "transport.h" |
37 | 37 |
#include "msg_logger.h" |
38 |
+#include "ip_util.h" |
|
38 | 39 |
|
39 | 40 |
#include "log.h" |
40 | 41 |
|
... | ... |
@@ -65,8 +66,22 @@ inline trans_timer** fetch_timer(unsigned int timer_type, trans_timer** base) |
65 | 66 |
return NULL; |
66 | 67 |
} |
67 | 68 |
|
69 |
+void sip_target_set::debug() |
|
70 |
+{ |
|
71 |
+ DBG("target list:"); |
|
72 |
+ |
|
73 |
+ for(list<sip_target>::iterator it = dest_list.begin(); |
|
74 |
+ it != dest_list.end(); it++) { |
|
75 |
+ |
|
76 |
+ DBG("\t%s:%u/%s to target list", |
|
77 |
+ am_inet_ntop(&it->ss).c_str(), |
|
78 |
+ am_get_port(&it->ss),it->trsp); |
|
79 |
+ } |
|
80 |
+} |
|
81 |
+ |
|
68 | 82 |
sip_trans::sip_trans() |
69 | 83 |
: msg(NULL), |
84 |
+ targets(NULL), |
|
70 | 85 |
retr_buf(NULL), |
71 | 86 |
retr_socket(NULL), |
72 | 87 |
retr_len(0), |
... | ... |
@@ -80,6 +95,7 @@ sip_trans::~sip_trans() |
80 | 95 |
{ |
81 | 96 |
reset_all_timers(); |
82 | 97 |
delete msg; |
98 |
+ delete targets; |
|
83 | 99 |
delete [] retr_buf; |
84 | 100 |
if(retr_socket){ |
85 | 101 |
dec_ref(retr_socket); |
... | ... |
@@ -35,6 +35,9 @@ |
35 | 35 |
|
36 | 36 |
#include <sys/socket.h> |
37 | 37 |
|
38 |
+#include <list> |
|
39 |
+using std::list; |
|
40 |
+ |
|
38 | 41 |
struct sip_msg; |
39 | 42 |
class trsp_socket; |
40 | 43 |
class msg_logger; |
... | ... |
@@ -114,7 +117,7 @@ struct sip_target |
114 | 117 |
|
115 | 118 |
const sip_target& operator = (const sip_target& target) { |
116 | 119 |
memcpy(&ss,&target.ss,sizeof(sockaddr_storage)); |
117 |
- memcpy(trsp,target.trsp,SIP_TRSP_SIZE_MAX); |
|
120 |
+ memcpy(trsp,target.trsp,SIP_TRSP_SIZE_MAX+1); |
|
118 | 121 |
return target; |
119 | 122 |
} |
120 | 123 |
|
... | ... |
@@ -153,6 +156,8 @@ struct sip_target_set |
153 | 156 |
return has_next(); |
154 | 157 |
} |
155 | 158 |
|
159 |
+ void debug(); |
|
160 |
+ |
|
156 | 161 |
private: |
157 | 162 |
sip_target_set(const sip_target_set&) {} |
158 | 163 |
}; |
... | ... |
@@ -186,6 +191,9 @@ class sip_trans |
186 | 191 |
/** Dialog-ID used for UAC transactions */ |
187 | 192 |
cstring dialog_id; |
188 | 193 |
|
194 |
+ /** Destination list for requests */ |
|
195 |
+ sip_target_set* targets; |
|
196 |
+ |
|
189 | 197 |
/** |
190 | 198 |
* Retransmission buffer |
191 | 199 |
* - UAC transaction: ACK |
... | ... |
@@ -791,14 +791,16 @@ int _trans_layer::set_next_hop(sip_msg* msg, |
791 | 791 |
} |
792 | 792 |
|
793 | 793 |
|
794 |
-int _trans_layer::set_destination_ip(sip_msg* msg, cstring* next_hop, |
|
795 |
- unsigned short next_port) |
|
794 |
+int _trans_layer::set_destination_ip(const cstring* next_hop, |
|
795 |
+ unsigned short next_port, |
|
796 |
+ sockaddr_storage* remote_ip, |
|
797 |
+ dns_handle* h_dns) |
|
796 | 798 |
{ |
797 | 799 |
|
798 | 800 |
string nh = c2stlstr(*next_hop); |
799 | 801 |
|
800 | 802 |
DBG("checking whether '%s' is IP address...\n", nh.c_str()); |
801 |
- if (am_inet_pton(nh.c_str(), &(msg->remote_ip)) != 1) { |
|
803 |
+ if (am_inet_pton(nh.c_str(), remote_ip) != 1) { |
|
802 | 804 |
|
803 | 805 |
// nh does NOT contain a valid IP address |
804 | 806 |
|
... | ... |
@@ -810,11 +812,12 @@ int _trans_layer::set_destination_ip(sip_msg* msg, cstring* next_hop, |
810 | 812 |
} else { |
811 | 813 |
string srv_name = "_sip._udp." + nh; |
812 | 814 |
|
813 |
- DBG("no port specified, looking up SRV '%s'...\n", srv_name.c_str()); |
|
815 |
+ DBG("no port specified, looking up SRV '%s'...\n", |
|
816 |
+ srv_name.c_str()); |
|
814 | 817 |
|
815 | 818 |
if(!resolver::instance()->resolve_name(srv_name.c_str(), |
816 |
- &(msg->h_dns), |
|
817 |
- &(msg->remote_ip),IPv4)){ |
|
819 |
+ h_dns,remote_ip, |
|
820 |
+ IPv4)){ |
|
818 | 821 |
return 0; |
819 | 822 |
} |
820 | 823 |
|
... | ... |
@@ -822,27 +825,62 @@ int _trans_layer::set_destination_ip(sip_msg* msg, cstring* next_hop, |
822 | 825 |
} |
823 | 826 |
} |
824 | 827 |
|
825 |
- memset(&(msg->remote_ip),0,sizeof(sockaddr_storage)); |
|
828 |
+ memset(remote_ip,0,sizeof(sockaddr_storage)); |
|
826 | 829 |
int err = resolver::instance()->resolve_name(nh.c_str(), |
827 |
- &(msg->h_dns), |
|
828 |
- &(msg->remote_ip),IPv4); |
|
830 |
+ h_dns,remote_ip, |
|
831 |
+ IPv4); |
|
829 | 832 |
if(err < 0){ |
830 | 833 |
ERROR("Unresolvable Request URI domain\n"); |
831 | 834 |
return -478; |
832 | 835 |
} |
833 | 836 |
} |
834 | 837 |
|
835 |
- if(!am_get_port(&msg->remote_ip)) { |
|
838 |
+ if(!am_get_port(remote_ip)) { |
|
836 | 839 |
if(!next_port) next_port = 5060; |
837 |
- am_set_port(&msg->remote_ip,next_port); |
|
840 |
+ am_set_port(remote_ip,next_port); |
|
838 | 841 |
} |
839 | 842 |
|
840 | 843 |
DBG("set destination to %s:%u\n", |
841 |
- nh.c_str(), am_get_port(&msg->remote_ip)); |
|
844 |
+ nh.c_str(), am_get_port(remote_ip)); |
|
842 | 845 |
|
843 | 846 |
return 0; |
844 | 847 |
} |
845 | 848 |
|
849 |
+int _trans_layer::resolve_targets(const list<sip_destination>& dest_list, |
|
850 |
+ sip_target_set* targets) |
|
851 |
+{ |
|
852 |
+ for(list<sip_destination>::const_iterator it = dest_list.begin(); |
|
853 |
+ it != dest_list.end(); it++) { |
|
854 |
+ |
|
855 |
+ sip_target t; |
|
856 |
+ dns_handle h_dns; |
|
857 |
+ |
|
858 |
+ DBG("sip_destination: %.*s:%u/%.*s", |
|
859 |
+ it->host.len,it->host.s, |
|
860 |
+ it->port, |
|
861 |
+ it->trsp.len,it->trsp.s); |
|
862 |
+ |
|
863 |
+ if(set_destination_ip(&it->host,it->port,&t.ss,&h_dns) != 0) { |
|
864 |
+ ERROR("Unresolvable destination"); |
|
865 |
+ return -478; |
|
866 |
+ } |
|
867 |
+ if(it->trsp.len && (it->trsp.len <= SIP_TRSP_SIZE_MAX)) { |
|
868 |
+ memcpy(t.trsp,it->trsp.s,it->trsp.len); |
|
869 |
+ t.trsp[it->trsp.len] = '\0'; |
|
870 |
+ } |
|
871 |
+ else { |
|
872 |
+ t.trsp[0] = '\0'; |
|
873 |
+ } |
|
874 |
+ |
|
875 |
+ do { |
|
876 |
+ targets->dest_list.push_back(t); |
|
877 |
+ |
|
878 |
+ } while(h_dns.next_ip(&t.ss) == 0); |
|
879 |
+ } |
|
880 |
+ |
|
881 |
+ return 0; |
|
882 |
+} |
|
883 |
+ |
|
846 | 884 |
static void set_err_reply_from_req(sip_msg* err, sip_msg* req, |
847 | 885 |
int code, const char* reason) |
848 | 886 |
{ |
... | ... |
@@ -1048,7 +1086,7 @@ static int generate_and_parse_new_msg(sip_msg* msg, sip_msg*& p_msg) |
1048 | 1086 |
p_msg = new sip_msg(); |
1049 | 1087 |
p_msg->buf = new char[request_len+1]; |
1050 | 1088 |
p_msg->len = request_len; |
1051 |
- p_msg->h_dns = msg->h_dns; |
|
1089 |
+ //p_msg->h_dns = msg->h_dns; |
|
1052 | 1090 |
|
1053 | 1091 |
// generate it |
1054 | 1092 |
char* c = p_msg->buf; |
... | ... |
@@ -1109,88 +1147,89 @@ int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt, |
1109 | 1147 |
assert(msg); |
1110 | 1148 |
assert(tt); |
1111 | 1149 |
|
1112 |
- cstring next_hop; |
|
1113 |
- unsigned short next_port=0; |
|
1114 |
- cstring next_trsp; |
|
1150 |
+ // cstring next_hop; |
|
1151 |
+ // unsigned short next_port=0; |
|
1152 |
+ // cstring next_trsp; |
|
1115 | 1153 |
|
1116 | 1154 |
int res=0; |
1155 |
+ list<sip_destination> dest_list; |
|
1117 | 1156 |
if (_next_hop.len) { |
1118 | 1157 |
|
1119 |
- list<sip_destination> dest_list; |
|
1120 | 1158 |
res = parse_next_hop(_next_hop,dest_list); |
1121 |
- if(res) { |
|
1159 |
+ if(res || dest_list.empty()) { |
|
1122 | 1160 |
DBG("parse_next_hop %.*s failed (%i)\n",_next_hop.len, _next_hop.s, res); |
1123 | 1161 |
return res; |
1124 | 1162 |
} |
1125 | 1163 |
|
1126 |
- if(dest_list.size() == 1) { |
|
1127 |
- const sip_destination& dest = dest_list.front(); |
|
1128 |
- next_hop = dest.host; |
|
1129 |
- next_port = dest.port; |
|
1130 |
- next_trsp = dest.trsp; |
|
1131 |
- DBG("single next-hop: <%.*s:%u/%.*s>", |
|
1132 |
- next_hop.len,next_hop.s,next_port, |
|
1133 |
- next_trsp.len,next_trsp.s); |
|
1134 |
- } |
|
1135 |
- else if(dest_list.size() > 1) { |
|
1136 |
- dns_ip_entry* e = new dns_ip_entry(); |
|
1137 |
- if(e->fill_ip_list(dest_list) < 0) { |
|
1138 |
- delete e; |
|
1139 |
- return -1; |
|
1140 |
- } |
|
1141 |
- |
|
1142 |
- inc_ref(e); |
|
1143 |
- //TODO: avoid to loose the transport from the next-hop-list |
|
1144 |
- e->next_ip(&msg->h_dns,&msg->remote_ip); |
|
1145 |
- DBG("destination set to <%s>\n", |
|
1146 |
- get_addr_str(&msg->remote_ip).c_str()); |
|
1147 |
- } |
|
1164 |
+ // if(dest_list.size() == 1) { |
|
1165 |
+ // const sip_destination& dest = dest_list.front(); |
|
1166 |
+ // next_hop = dest.host; |
|
1167 |
+ // next_port = dest.port; |
|
1168 |
+ // next_trsp = dest.trsp; |
|
1169 |
+ // DBG("single next-hop: <%.*s:%u/%.*s>", |
|
1170 |
+ // next_hop.len,next_hop.s,next_port, |
|
1171 |
+ // next_trsp.len,next_trsp.s); |
|
1172 |
+ // } |
|
1173 |
+ // else if(dest_list.size() > 1) { |
|
1174 |
+ // dns_ip_entry* e = new dns_ip_entry(); |
|
1175 |
+ // if(e->fill_ip_list(dest_list) < 0) { |
|
1176 |
+ // delete e; |
|
1177 |
+ // return -1; |
|
1178 |
+ // } |
|
1179 |
+ // inc_ref(e); |
|
1180 |
+ // //TODO: avoid to loose the transport from the next-hop-list |
|
1181 |
+ // e->next_ip(&msg->h_dns,&msg->remote_ip); |
|
1182 |
+ // DBG("destination set to <%s>\n", |
|
1183 |
+ // get_addr_str(&msg->remote_ip).c_str()); |
|
1184 |
+ // } |
|
1148 | 1185 |
} |
1149 | 1186 |
else { |
1150 |
- if(set_next_hop(msg,&next_hop,&next_port,&next_trsp) < 0){ |
|
1187 |
+ sip_destination dest; |
|
1188 |
+ if(set_next_hop(msg,&dest.host,&dest.port,&dest.trsp) < 0){ |
|
1151 | 1189 |
DBG("set_next_hop failed\n"); |
1152 | 1190 |
return -1; |
1153 | 1191 |
} |
1192 |
+ dest_list.push_back(dest); |
|
1154 | 1193 |
} |
1155 | 1194 |
|
1156 | 1195 |
string uri_buffer; // must have the same scope as 'msg' |
1157 | 1196 |
prepare_strict_routing(msg,uri_buffer); |
1158 | 1197 |
|
1159 |
- if(next_hop.len) { |
|
1160 |
- res = set_destination_ip(msg,&next_hop,next_port); |
|
1161 |
- if(res < 0){ |
|
1162 |
- DBG("set_destination_ip failed\n"); |
|
1163 |
- return res; |
|
1164 |
- } |
|
1198 |
+ auto_ptr<sip_target_set> targets(new sip_target_set()); |
|
1199 |
+ res = resolve_targets(dest_list,targets.get()); |
|
1200 |
+ if(res < 0){ |
|
1201 |
+ DBG("resolve_targets failed\n"); |
|
1202 |
+ return res; |
|
1165 | 1203 |
} |
1166 | 1204 |
|
1167 |
- if(!(flags & TR_FLAG_DISABLE_BL) && |
|
1168 |
- tr_blacklist::instance()->exist(&msg->remote_ip)) { |
|
1205 |
+ targets->debug(); |
|
1169 | 1206 |
|
1170 |
- sockaddr_storage sa; |
|
1171 |
- do { |
|
1172 |
- memset(&sa,0,sizeof(sockaddr_storage)); |
|
1173 |
- |
|
1174 |
- // get the next ip |
|
1175 |
- if(msg->h_dns.next_ip(&sa) < 0){ |
|
1176 |
- DBG("next_ip(): no more destinations! reply 500"); |
|
1177 |
- sip_msg err; |
|
1178 |
- set_err_reply_from_req(&err,msg,500, |
|
1179 |
- "All destinations blacklisted"); |
|
1180 |
- ua->handle_sip_reply(c2stlstr(dialog_id),&err); |
|
1181 |
- return 0; |
|
1182 |
- } |
|
1183 |
- |
|
1184 |
- //If a SRV record is involved, the port number |
|
1185 |
- // should have been set by h_dns.next_ip(...). |
|
1186 |
- if(!am_get_port(&sa)){ |
|
1187 |
- //Else, we copy the old port number |
|
1188 |
- am_set_port(&sa,am_get_port(&msg->remote_ip)); |
|
1189 |
- } |
|
1190 |
- } while(tr_blacklist::instance()->exist(&sa)); |
|
1191 |
- |
|
1192 |
- memcpy(&msg->remote_ip,&sa,sizeof(sockaddr_storage)); |
|
1193 |
- } |
|
1207 |
+ cstring next_trsp; |
|
1208 |
+ targets->reset_iterator(); |
|
1209 |
+ do { |
|
1210 |
+ if(!targets->has_next()) { |
|
1211 |
+ DBG("next_ip(): no more destinations! reply 500"); |
|
1212 |
+ sip_msg err; |
|
1213 |
+ set_err_reply_from_req(&err,msg,500, |
|
1214 |
+ "No destination available"); |
|
1215 |
+ ua->handle_sip_reply(c2stlstr(dialog_id),&err); |
|
1216 |
+ return 0; |
|
1217 |
+ } |
|
1218 |
+ |
|
1219 |
+ targets->copy_next(&msg->remote_ip,&next_trsp); |
|
1220 |
+ targets->next(); |
|
1221 |
+ |
|
1222 |
+ //TODO: take care of port manipulation in SRV case |
|
1223 |
+ // and the likes |
|
1224 |
+ // |
|
1225 |
+ // //If a SRV record is involved, the port number |
|
1226 |
+ // // should have been set by h_dns.next_ip(...). |
|
1227 |
+ // if(!am_get_port(&sa)){ |
|
1228 |
+ // //Else, we copy the old port number |
|
1229 |
+ // am_set_port(&sa,am_get_port(&msg->remote_ip)); |
|
1230 |
+ // } |
|
1231 |
+ } while(!(flags & TR_FLAG_DISABLE_BL) && |
|
1232 |
+ tr_blacklist::instance()->exist(&msg->remote_ip)); |
|
1194 | 1233 |
|
1195 | 1234 |
if((out_interface < 0) |
1196 | 1235 |
|| ((unsigned int)out_interface >= transports.size())) { |
... | ... |
@@ -1279,9 +1318,14 @@ int _trans_layer::send_request(sip_msg* msg, trans_ticket* tt, |
1279 | 1318 |
return send_err; |
1280 | 1319 |
} |
1281 | 1320 |
|
1282 |
- // TODO: |
|
1283 |
- // - save flags in transaction |
|
1321 |
+ // save flags & target set in transaction |
|
1284 | 1322 |
tt->_t->flags = flags; |
1323 |
+ tt->_t->targets = targets.release(); |
|
1324 |
+ |
|
1325 |
+ if(tt->_t->targets->has_next()){ |
|
1326 |
+ tt->_t->reset_timer(STIMER_M,M_TIMER, |
|
1327 |
+ tt->_bucket->get_id()); |
|
1328 |
+ } |
|
1285 | 1329 |
|
1286 | 1330 |
DBG("logger = %p\n",logger); |
1287 | 1331 |
|
... | ... |
@@ -1987,10 +2031,6 @@ int _trans_layer::update_uac_request(trans_bucket* bucket, sip_trans*& t, sip_ms |
1987 | 2031 |
break; |
1988 | 2032 |
} |
1989 | 2033 |
|
1990 |
- if(!msg->h_dns.eoip()){ |
|
1991 |
- t->reset_timer(STIMER_M,M_TIMER,bucket->get_id()); |
|
1992 |
- } |
|
1993 |
- |
|
1994 | 2034 |
return 0; |
1995 | 2035 |
} |
1996 | 2036 |
|
... | ... |
@@ -2463,25 +2503,38 @@ int _trans_layer::try_next_ip(trans_bucket* bucket, sip_trans* tr, |
2463 | 2503 |
bool use_new_trans) |
2464 | 2504 |
{ |
2465 | 2505 |
tr->clear_timer(STIMER_M); |
2506 |
+ |
|
2507 |
+ cstring next_trsp; |
|
2466 | 2508 |
sockaddr_storage sa; |
2509 |
+ |
|
2467 | 2510 |
do { |
2468 | 2511 |
memset(&sa,0,sizeof(sockaddr_storage)); |
2469 | 2512 |
|
2470 | 2513 |
// get the next ip |
2471 |
- if(tr->msg->h_dns.next_ip(&sa) < 0){ |
|
2514 |
+ if(!tr->targets->has_next()){ |
|
2472 | 2515 |
DBG("no more destinations!"); |
2473 | 2516 |
return -1; |
2474 | 2517 |
} |
2475 |
- |
|
2476 |
- //If a SRV record is involved, the port number |
|
2477 |
- // should have been set by h_dns.next_ip(...). |
|
2478 |
- if(!am_get_port(&sa)){ |
|
2479 |
- //Else, we copy the old port number |
|
2480 |
- am_set_port(&sa,am_get_port(&tr->msg->remote_ip)); |
|
2481 |
- } |
|
2518 |
+ |
|
2519 |
+ tr->targets->copy_next(&sa,&next_trsp); |
|
2520 |
+ tr->targets->next(); |
|
2521 |
+ |
|
2522 |
+ //TODO: take care of port manipulation in SRV case |
|
2523 |
+ // and the likes |
|
2524 |
+ // |
|
2525 |
+ // //If a SRV record is involved, the port number |
|
2526 |
+ // // should have been set by h_dns.next_ip(...). |
|
2527 |
+ // if(!am_get_port(&sa)){ |
|
2528 |
+ // //Else, we copy the old port number |
|
2529 |
+ // am_set_port(&sa,am_get_port(&tr->msg->remote_ip)); |
|
2530 |
+ // } |
|
2482 | 2531 |
} while(!(tr->flags & TR_FLAG_DISABLE_BL) && |
2483 | 2532 |
tr_blacklist::instance()->exist(&sa)); |
2484 | 2533 |
|
2534 |
+ //TODO: support transport changes |
|
2535 |
+ // -> potentially find another socket |
|
2536 |
+ // if next_trsp is different from the |
|
2537 |
+ // current socket's transport |
|
2485 | 2538 |
|
2486 | 2539 |
if(use_new_trans) { |
2487 | 2540 |
string n_uri; |
... | ... |
@@ -2526,6 +2579,10 @@ int _trans_layer::try_next_ip(trans_bucket* bucket, sip_trans* tr, |
2526 | 2579 |
tr->clear_timer(STIMER_A); |
2527 | 2580 |
tr->state = TS_ABANDONED; |
2528 | 2581 |
|
2582 |
+ // take over target set |
|
2583 |
+ n_tr->targets = tr->targets; |
|
2584 |
+ tr->targets = NULL; |
|
2585 |
+ |
|
2529 | 2586 |
// restore old R-URI |
2530 | 2587 |
tr->msg->u.request->ruri_str = old_uri; |
2531 | 2588 |
|
... | ... |
@@ -2538,8 +2595,7 @@ int _trans_layer::try_next_ip(trans_bucket* bucket, sip_trans* tr, |
2538 | 2595 |
tr->reset_timer(t_bf,t_bf->type); |
2539 | 2596 |
} |
2540 | 2597 |
|
2541 |
- bucket->append(tr); |
|
2542 |
- |
|
2598 |
+ bucket->append(tr); |
|
2543 | 2599 |
} |
2544 | 2600 |
else { |
2545 | 2601 |
// copy the new address back |
... | ... |
@@ -2598,7 +2654,7 @@ int _trans_layer::try_next_ip(trans_bucket* bucket, sip_trans* tr, |
2598 | 2654 |
} |
2599 | 2655 |
} |
2600 | 2656 |
|
2601 |
- if(!tr->msg->h_dns.eoip()) |
|
2657 |
+ if(tr->targets->has_next()) |
|
2602 | 2658 |
tr->reset_timer(STIMER_M,M_TIMER,bucket->get_id()); |
2603 | 2659 |
|
2604 | 2660 |
return 0; |
... | ... |
@@ -33,6 +33,8 @@ |
33 | 33 |
#include "singleton.h" |
34 | 34 |
#include "atomic_types.h" |
35 | 35 |
|
36 |
+#include "parse_next_hop.h" |
|
37 |
+ |
|
36 | 38 |
#include <list> |
37 | 39 |
using std::list; |
38 | 40 |
|
... | ... |
@@ -47,9 +49,11 @@ using std::map; |
47 | 49 |
|
48 | 50 |
struct sip_msg; |
49 | 51 |
struct sip_uri; |
50 |
-class sip_trans; |
|
52 |
+class sip_trans; |
|
51 | 53 |
struct sip_header; |
52 | 54 |
struct sockaddr_storage; |
55 |
+struct dns_handle; |
|
56 |
+struct sip_target_set; |
|
53 | 57 |
|
54 | 58 |
class trans_ticket; |
55 | 59 |
class trans_bucket; |
... | ... |
@@ -247,15 +251,22 @@ protected: |
247 | 251 |
* Fills the address structure passed and modifies |
248 | 252 |
* R-URI and Route headers as needed. |
249 | 253 |
*/ |
250 |
- int set_next_hop(sip_msg* msg, |
|
251 |
- cstring* next_hop, |
|
252 |
- unsigned short* next_port, |
|
253 |
- cstring* next_trsp); |
|
254 |
+ int set_next_hop(sip_msg* msg, cstring* next_hop, |
|
255 |
+ unsigned short* next_port, cstring* next_trsp); |
|
256 |
+ |
|
257 |
+ /** |
|
258 |
+ * Transforms all elements of a destination list into |
|
259 |
+ * a target set, thus resolving all DNS names and |
|
260 |
+ * converting IPs into a sockaddr_storage. |
|
261 |
+ */ |
|
262 |
+ int resolve_targets(const list<sip_destination>& dest_list, |
|
263 |
+ sip_target_set* targets); |
|
254 | 264 |
|
255 | 265 |
/** |
256 | 266 |
* Fills msg->remote_ip according to next_hop and next_port. |
257 | 267 |
*/ |
258 |
- int set_destination_ip(sip_msg* msg, cstring* next_hop, unsigned short next_port); |
|
268 |
+ int set_destination_ip(const cstring* next_hop, unsigned short next_port, |
|
269 |
+ sockaddr_storage* remote_ip, dns_handle* h_dns); |
|
259 | 270 |
|
260 | 271 |
sip_trans* copy_uac_trans(sip_trans* tr); |
261 | 272 |
|