[sr-dev] git:master:2f080bd3: tm: uac: Add support for onsend route to local request

Alex Hermann alex at speakup.nl
Tue Aug 30 13:46:52 CEST 2016


Module: kamailio
Branch: master
Commit: 2f080bd3af63678b900f9f537afbd187007eb089
URL: https://github.com/kamailio/kamailio/commit/2f080bd3af63678b900f9f537afbd187007eb089

Author: Alex Hermann <alex at speakup.nl>
Committer: Alex Hermann <alex at speakup.nl>
Date: 2016-07-28T12:02:15+02:00

tm: uac: Add support for onsend route to local request

---

Modified: modules/tm/uac.c

---

Diff:  https://github.com/kamailio/kamailio/commit/2f080bd3af63678b900f9f537afbd187007eb089.diff
Patch: https://github.com/kamailio/kamailio/commit/2f080bd3af63678b900f9f537afbd187007eb089.patch

---

diff --git a/modules/tm/uac.c b/modules/tm/uac.c
index 6f165ae..bb4149a 100644
--- a/modules/tm/uac.c
+++ b/modules/tm/uac.c
@@ -57,6 +57,7 @@
 #include "../../action.h"
 #include "../../onsend.h"
 #include "t_lookup.h"
+#include "t_fwd.h"
 #endif
 
 #define FROM_TAG_LEN (MD5_LEN + 1 /* - */ + CRC16_LEN) /* length of FROM tags */
@@ -590,23 +591,63 @@ int prepare_req_within(uac_req_t *uac_r,
 	return -1;
 }
 
-static inline void send_prepared_request_impl(struct retr_buf *request, int retransmit)
+static inline int send_prepared_request_impl(struct retr_buf *request, int retransmit, int branch)
 {
+	struct cell *t;
+	struct sip_msg *p_msg;
+	struct ua_client *uac;
+	struct ip_addr ip; /* logging */
+	int ret;
+
+	t = request->my_T;
+	uac = &t->uac[branch];
+	p_msg = t->uas.request;
+
 	if (SEND_BUFFER(request) == -1) {
 		LOG(L_ERR, "t_uac: Attempt to send to precreated request failed\n");
 	}
-	else if (unlikely(has_tran_tmcbs(request->my_T, TMCB_REQUEST_SENT)))
+	else if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_SENT)))
 		/* we don't know the method here */
-			run_trans_callbacks_with_buf(TMCB_REQUEST_SENT, request, 0, 0,
+		run_trans_callbacks_with_buf(TMCB_REQUEST_SENT, &uac->request, 0, 0,
 			TMCB_LOCAL_F);
-	
-	if (retransmit && (start_retr(request)!=0))
-		LOG(L_CRIT, "BUG: t_uac: failed to start retr. for %p\n", request);
+
+	su2ip_addr(&ip, &uac->request.dst.to);
+	DBG("send_prepared_request_impl: uac: %p  branch: %d  to %s:%d\n",
+			uac, branch, ip_addr2a(&ip), su_getport(&uac->request.dst.to));
+
+	if (run_onsend(p_msg, &uac->request.dst, uac->request.buffer,
+			uac->request.buffer_len)==0){
+		uac->last_received=408;
+		su2ip_addr(&ip, &uac->request.dst.to);
+		DBG("t_uac: onsend_route dropped msg. to %s:%d (%d)\n",
+						ip_addr2a(&ip), su_getport(&uac->request.dst.to),
+						uac->request.dst.proto);
+#ifdef USE_DNS_FAILOVER
+		/* if the destination resolves to more ips, add another
+			*  branch/uac */
+		ret = add_uac_dns_fallback(t, p_msg, uac, retransmit);
+		if (ret > 0) {
+			su2ip_addr(&ip, &uac->request.dst.to);
+			DBG("t_uac: send on branch %d failed "
+					"(onsend_route), trying another ip %s:%d (%d)\n",
+					branch, ip_addr2a(&ip),
+					su_getport(&uac->request.dst.to),
+					uac->request.dst.proto);
+			/* success, return new branch */
+			return ret;
+		}
+#endif /* USE_DNS_FAILOVER*/
+		return -1;
+	}
+
+	if (retransmit && (start_retr(&uac->request)!=0))
+		LOG(L_CRIT, "BUG: t_uac: failed to start retr. for %p\n", &uac->request);
+	return 0;
 }
 
 void send_prepared_request(struct retr_buf *request)
 {
-	send_prepared_request_impl(request, 1 /* retransmit */);
+	send_prepared_request_impl(request, 1 /* retransmit */, 0);
 }
 
 /*
@@ -628,11 +669,27 @@ int t_uac_with_ids(uac_req_t *uac_r,
 	struct cell *cell;
 	int ret;
 	int is_ack;
+	int branch_ret;
+	int i;
+	branch_bm_t added_branches = 1;
 
 	ret = t_uac_prepare(uac_r, &request, &cell);
 	if (ret < 0) return ret;
 	is_ack = (uac_r->method->len == 3) && (memcmp("ACK", uac_r->method->s, 3)==0) ? 1 : 0;
-	send_prepared_request_impl(request, !is_ack /* retransmit */);
+
+	/* equivalent loop to the one in t_forward_nonack */
+	for (i=0; i<cell->nr_of_outgoings; i++) {
+		if (added_branches & (1<<i)) {
+			branch_ret=send_prepared_request_impl(request, !is_ack /* retransmit */, i);
+			if (branch_ret>=0){ /* some kind of success */
+				if (branch_ret>i) {
+					/* new branch added */
+					added_branches |= 1<<branch_ret;
+				}
+			}
+		}
+	}
+
 	if (is_ack) {
 		if (cell) free_cell(cell);
 		if (ret_index && ret_label)




More information about the sr-dev mailing list