Browse code

tm: merge t_append_branches() and t_append_branch_by_contact()

Because the implementation of the functions
't_append_branches()' and 't_append_branch_by_contact()' is pretty
much the same, it's proposed to merge them into one:
't_append_branches()'

The way how the function acts now depends on if the contact
parameter of str type is given or not (empty or not).
If the contact parameter is given, then only a desired location
is meant for appending. If not found in the location table,
an append will not happen for this AOR.

Otherwise create branches for all existing location records
of this particular AOR. Search for locations is done in the location table.

Donat Zenichev authored on 14/11/2021 20:59:58 • Victor Seva committed on 19/11/2021 08:18:55
Showing 4 changed files
... ...
@@ -46,7 +46,18 @@
46 46
 #include "t_reply.h"
47 47
 #include "t_append_branches.h"
48 48
 
49
-int t_append_branches(void) {
49
+/* this function can act in two ways:
50
+ * - first way, create branches for all existing location records
51
+ *   of this particular AOR. Search for locations is done in
52
+ *   the location table.
53
+ * - second way, if the contact parameter is given,
54
+ *   then only a desired location is meant for appending,
55
+ *   if not found in the location table, an append will not happen
56
+ *   for this AOR.
57
+ *
58
+ *   If the contact parameter is given, it must be of syntax:
59
+ *     sip:<user>@<host>:<port>   (without parameters) */
60
+int t_append_branches(str * contact) {
50 61
 	struct cell *t = NULL;
51 62
 	struct sip_msg *orig_msg = NULL;
52 63
 	struct sip_msg *faked_req;
... ...
@@ -59,7 +70,7 @@ int t_append_branches(void) {
59 70
 	str current_uri;
60 71
 	str dst_uri, path, instance, ruid, location_ua;
61 72
 	struct socket_info* si;
62
-	int q, i, found;
73
+	int q, i, found, append;
63 74
 	flag_t backup_bflags = 0;
64 75
 	flag_t bflags = 0;
65 76
 	int new_branch, branch_ret, lowest_ret;
... ...
@@ -125,212 +136,25 @@ int t_append_branches(void) {
125 136
 										&bflags, &si, &ruid, &instance, &location_ua))) {
126 137
 		LM_DBG("Current uri %.*s\n",current_uri.len, current_uri.s);
127 138
 
128
-		found = 0;
129
-		for (i=0; i<outgoings; i++) {
130
-			if (t->uac[i].ruid.len == ruid.len
131
-					&& !memcmp(t->uac[i].ruid.s, ruid.s, ruid.len)
132
-					&& t->uac[i].uri.len == current_uri.len
133
-					&& !memcmp(t->uac[i].uri.s, current_uri.s, current_uri.len)) {
134
-				LM_DBG("branch already added [%.*s]\n", ruid.len, ruid.s);
135
-				found = 1;
136
-				break;
137
-			}
138
-		}
139
-		if (found)
140
-			continue;
141
-
142
-		setbflagsval(0, bflags);
143
-		new_branch=add_uac( t, faked_req, &current_uri,
144
-					(dst_uri.len) ? (&dst_uri) : &current_uri,
145
-					&path, 0, si, faked_req->fwd_send_flags,
146
-					PROTO_NONE, (dst_uri.len)?0:UAC_SKIP_BR_DST_F, &instance,
147
-					&ruid, &location_ua);
148
-
149
-		LM_DBG("added branch [%.*s] with ruid [%.*s]\n",
150
-				current_uri.len, current_uri.s, ruid.len, ruid.s);
151
-
152
-		/* test if cancel was received meanwhile */
153
-		if (t->flags & T_CANCELED) goto canceled;
154
-
155
-		if (new_branch>=0)
156
-			added_branches |= 1<<new_branch;
157
-		else
158
-			lowest_ret=MIN_int(lowest_ret, new_branch);
159
-	}
160
-
161
-	clear_branches();
162
-
163
-	LM_DBG("Call %.*s: %d (%d) outgoing branches after clear_branches()\n",
164
-			orig_msg->callid->body.len, orig_msg->callid->body.s,outgoings, nr_branches);
165
-	setbflagsval(0, backup_bflags);
166
-
167
-	/* update message flags, if changed in branch route */
168
-	t->uas.request->flags = faked_req->flags;
169
-
170
-	if (added_branches==0) {
171
-		if(lowest_ret!=E_CFG)
172
-			LM_ERR("failure to add branches (%d)\n", lowest_ret);
173
-		ser_error=lowest_ret;
174
-		ret = lowest_ret;
175
-		goto done;
176
-	}
139
+		/* if the contact parameter is given, then append by
140
+			an exact location that has been requested for this function call */
141
+		if (contact->s != NULL && contact->len != 0) {
177 142
 
178
-	ser_error=0; /* clear branch adding errors */
179
-	/* send them out now */
180
-	success_branch=0;
181
-	/* since t_append_branch can only be called from REQUEST_ROUTE, always lock replies */
143
+			LM_DBG("Comparing requested contact <%.*s> against location <%.*s>\n",
144
+							contact->len, contact->s, current_uri.len, current_uri.s);
182 145
 
183
-	for (i=outgoings; i<t->nr_of_outgoings; i++) {
184
-		if (added_branches & (1<<i)) {
185
-			branch_ret=t_send_branch(t, i, faked_req , 0, 0 /* replies are already locked */ );
186
-			if (branch_ret>=0){ /* some kind of success */
187
-				if (branch_ret==i) { /* success */
188
-					success_branch++;
189
-					if (unlikely(has_tran_tmcbs(t, TMCB_REQUEST_OUT)))
190
-						run_trans_callbacks_with_buf( TMCB_REQUEST_OUT,
191
-								&t->uac[nr_branches].request,
192
-								faked_req, 0, TMCB_NONE_F);
193
-				}
194
-				else /* new branch added */
195
-					added_branches |= 1<<branch_ret;
146
+			append = 1;
147
+			if (strstr(current_uri.s, contact->s) == NULL) {
148
+				append = 0; /* this while cycle will be stopped */
196 149
 			}
197
-		}
198
-	}
199
-	if (success_branch<=0) {
200
-		/* return always E_SEND for now
201
-		 * (the real reason could be: denied by onsend routes, blocklisted,
202
-		 *  send failed or any of the errors listed before + dns failed
203
-		 *  when attempting dns failover) */
204
-		ser_error=E_SEND;
205
-		/* else return the last error (?) */
206
-		ret = -1;
207
-		goto done;
208
-	}
209
-
210
-	ser_error=0; /* clear branch send errors, we have overall success */
211
-	set_kr(REQ_FWDED);
212
-	ret = success_branch;
213
-	goto done;
214
-
215
-canceled:
216
-	LM_DBG("cannot append branches to a canceled transaction\n");
217
-	/* reset processed branches */
218
-	clear_branches();
219
-	/* restore backup flags from initial env */
220
-	setbflagsval(0, backup_bflags);
221
-	/* update message flags, if changed in branch route */
222
-	t->uas.request->flags = faked_req->flags;
223
-	/* if needed unlock transaction's replies */
224
-		/* restore the number of outgoing branches
225
-		 * since new branches have not been completed */
226
-	t->nr_of_outgoings = outgoings;
227
-	ser_error=E_CANCELED;
228
-	ret = -1;
229
-done:
230
-	/* restore original environment and free the fake msg */
231
-	faked_env( t, 0, 0);
232
-	free_faked_req(faked_req, faked_req_len);
233
-
234
-	if (likely(replies_locked)) {
235
-		replies_locked = 0;
236
-		UNLOCK_REPLIES(t);
237
-	}
238
-	return ret;
239
-}
240
-
241
-/* append a new transaction based on desired Contact hf value
242
- * contact parameter must be of syntax (no hf parameters):
243
- * sip:<user>@<host>:<port> */
244
-int t_append_branch_by_contact(str * contact) {
245
-	struct cell *t = NULL;
246
-	struct sip_msg *orig_msg = NULL;
247
-	struct sip_msg *faked_req;
248
-	int faked_req_len = 0;
249
-
250
-	short outgoings;
251
-
252
-	int success_branch;
253
-
254
-	str current_uri;
255
-	str dst_uri, path, instance, ruid, location_ua;
256
-	struct socket_info* si;
257
-	int q, i, found, append;
258
-	flag_t backup_bflags = 0;
259
-	flag_t bflags = 0;
260
-	int new_branch, branch_ret, lowest_ret;
261
-	branch_bm_t	added_branches;
262
-	int replies_locked = 0;
263
-	int ret = 0;
264
-
265
-	t = get_t();
266
-	if(t == NULL)
267
-	{
268
-		LM_ERR("cannot get transaction\n");
269
-		return -1;
270
-	}
271
-
272
-	LM_DBG("transaction %u:%u in status %d\n", t->hash_index, t->label, t->uas.status);
273
-
274
-	/* test if transaction has already been canceled */
275
-	if (t->flags & T_CANCELED) {
276
-		ser_error=E_CANCELED;
277
-		return -1;
278
-	}
279
-
280
-	if ((t->uas.status >= 200 && t->uas.status<=399)
281
-			|| ((t->uas.status >= 600 && t->uas.status)
282
-				&& !(t->flags & (T_6xx | T_DISABLE_6xx))) ) {
283
-		LM_DBG("transaction %u:%u in status %d: cannot append new branch\n",
284
-				t->hash_index, t->label, t->uas.status);
285
-		return -1;
286
-	}
287
-
288
-	/* set the lock on the transaction here */
289
-	LOCK_REPLIES(t);
290
-	replies_locked = 1;
291
-	outgoings = t->nr_of_outgoings;
292
-	orig_msg = t->uas.request;
293
-
294
-	LM_DBG("Call %.*s: %d (%d) outgoing branches\n",orig_msg->callid->body.len,
295
-			orig_msg->callid->body.s,outgoings, nr_branches);
296
-
297
-	lowest_ret=E_UNSPEC;
298
-	added_branches=0;
299
-
300
-	/* it's a "late" branch so the on_branch variable has already been
301
-	reset by previous execution of t_forward_nonack: we use the saved
302
-	   value  */
303
-	if (t->on_branch_delayed) {
304
-		/* tell add_uac that it should run branch route actions */
305
-		set_branch_route(t->on_branch_delayed);
306
-	}
307
-	faked_req = fake_req(orig_msg, 0, NULL,	&faked_req_len);
308
-	if (faked_req==NULL) {
309
-		LM_ERR("fake_req failed\n");
310
-		return -1;
311
-	}
312
-
313
-	/* fake also the env. conforming to the fake msg */
314
-	faked_env( t, faked_req, 0);
315
-
316
-	/* DONE with faking ;-) -> run the failure handlers */
317
-	init_branch_iterator();
318 150
 
319
-	while((current_uri.s=next_branch( &current_uri.len, &q, &dst_uri, &path,
320
-										&bflags, &si, &ruid, &instance, &location_ua))) {
321
-		LM_DBG("Current uri %.*s\n",current_uri.len, current_uri.s);
151
+			/* do not append the branch if a contact does not match */
152
+			if (!append)
153
+				continue;
322 154
 
323
-		append = 1;
324
-		if (strstr(current_uri.s, contact->s) == NULL) {
325
-			append = 0;
155
+			LM_DBG("Branch will be appended for contact <%.*s>\n", contact->len, contact->s);
326 156
 		}
327 157
 
328
-		/* do not append the branch if a contact does not match */
329
-		if (!append)
330
-			continue;
331
-
332
-		LM_DBG("Branch will be appended for contact <%.*s>\n", contact->len, contact->s);
333
-
334 158
 		found = 0;
335 159
 		for (i=0; i<outgoings; i++) {
336 160
 			if (t->uac[i].ruid.len == ruid.len
... ...
@@ -442,4 +266,4 @@ done:
442 266
 		UNLOCK_REPLIES(t);
443 267
 	}
444 268
 	return ret;
445
-}
446 269
\ No newline at end of file
270
+}
... ...
@@ -31,11 +31,7 @@
31 31
 #include "../../core/proxy.h"
32 32
 #include "h_table.h"
33 33
 
34
-int t_append_branches(void);
35
-typedef int (*t_append_branches_f)(void);
36
-
37
-/* append a new transaction based on desired Contact hf value */
38
-int t_append_branch_by_contact(str * contact);
39
-typedef int (*t_append_branch_by_contact_f)(str * contact);
34
+int t_append_branches(str * contact);
35
+typedef int (*t_append_branches_f)(str * contact);
40 36
 
41 37
 #endif
... ...
@@ -134,7 +134,6 @@ int load_tm( struct tm_binds *tmb)
134 134
 	tmb->tm_ctx_get = tm_ctx_get;
135 135
 #endif
136 136
 	tmb->t_append_branches = t_append_branches;
137
-	tmb->t_append_branch_by_contact = t_append_branch_by_contact;
138 137
 	tmb->t_load_contacts = t_load_contacts;
139 138
 	tmb->t_next_contacts = t_next_contacts;
140 139
 	tmb->set_fr = t_set_fr;
... ...
@@ -117,7 +117,6 @@ struct tm_binds {
117 117
 	void* reserved5;
118 118
 #endif
119 119
 	t_append_branches_f	t_append_branches;
120
-	t_append_branch_by_contact_f	t_append_branch_by_contact;
121 120
 	cmd_function	t_load_contacts;
122 121
 	cmd_function	t_next_contacts;
123 122
 	tset_fr_f set_fr;