Skip to content

Commit 6af768f

Browse files
committed
registrar: Fix ping latency-based contact sorting
serialize_branches() was designed to always sort branches in descending "q" value order. This patch adds an optional serialize_branches() parameter which disables this behavior.
1 parent 0d494e5 commit 6af768f

File tree

5 files changed

+38
-25
lines changed

5 files changed

+38
-25
lines changed

action.c

+5-14
Original file line numberDiff line numberDiff line change
@@ -1958,27 +1958,18 @@ int do_action(struct action* a, struct sip_msg* msg)
19581958
break;
19591959
case SERIALIZE_BRANCHES_T:
19601960
script_trace("core", "serialize_branches", msg, a->file, a->line) ;
1961-
if (a->elem[0].type!=NUMBER_ST){
1962-
LM_ALERT("BUG in serialize_branches argument"
1963-
" type: %d\n", a->elem[0].type);
1964-
ret=E_BUG;
1965-
break;
1966-
}
1967-
if (serialize_branches(msg,(int)a->elem[0].u.number)!=0) {
1961+
if (serialize_branches(msg,(int)a->elem[0].u.number,
1962+
a->elem[1].u.data ? (int)a->elem[1].u.number : 0)!=0) {
19681963
LM_ERR("serialize_branches failed\n");
19691964
ret=E_UNSPEC;
19701965
break;
19711966
}
1972-
ret=1; /* continue processing */
1967+
ret=1;
19731968
break;
19741969
case NEXT_BRANCHES_T:
19751970
script_trace("core", "next_branches", msg, a->file, a->line) ;
1976-
if ((ret=next_branches(msg))<0) {
1977-
LM_ERR("next_branches failed\n");
1978-
ret=E_UNSPEC;
1979-
break;
1980-
}
1981-
/* continue processing */
1971+
if ((ret = next_branches(msg)) < 0)
1972+
LM_DBG("no more branches\n");
19821973
break;
19831974
case EQ_T:
19841975
case COLONEQ_T:

cfg.y

+6-1
Original file line numberDiff line numberDiff line change
@@ -2316,8 +2316,13 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T,
23162316
}
23172317
| FORCE_SEND_SOCKET error {$$=0; yyerror("missing '(' or ')' ?"); }
23182318
| SERIALIZE_BRANCHES LPAREN NUMBER RPAREN {
2319+
mk_action1( $$, SERIALIZE_BRANCHES_T,
2320+
NUMBER_ST, (void*)(long)$3);
2321+
}
2322+
| SERIALIZE_BRANCHES LPAREN NUMBER COMMA NUMBER RPAREN {
23192323
mk_action2( $$, SERIALIZE_BRANCHES_T,
2320-
NUMBER_ST, 0, (void*)(long)$3, 0);
2324+
NUMBER_ST, NUMBER_ST,
2325+
(void*)(long)$3, (void*)(long)$5);
23212326
}
23222327
| SERIALIZE_BRANCHES LPAREN error RPAREN {$$=0; yyerror("bad argument,"
23232328
" number expected");

modules/registrar/lookup.c

+14-4
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,21 @@ static str branch_uris[MAX_BRANCHES-1];
7373
ucontact_t **sorted_cts; /* always has an extra terminating NULL ptr */
7474
int sorted_cts_sz = 20;
7575

76-
static int cmp_ucontact(const void *ct1, const void *ct2)
76+
static int cmp_ucontact(const void *_ct1, const void *_ct2)
7777
{
78-
return
79-
(*(ucontact_t **)ct1)->sipping_latency -
80-
(*(ucontact_t **)ct2)->sipping_latency;
78+
ucontact_t *ct1 = *(ucontact_t **)_ct1, *ct2 = *(ucontact_t **)_ct2;
79+
80+
if (ct1->sipping_latency == 0) {
81+
if (ct2->sipping_latency == 0)
82+
return 0;
83+
84+
return 1;
85+
}
86+
87+
if (ct2->sipping_latency == 0)
88+
return -1;
89+
90+
return ct1->sipping_latency - ct2->sipping_latency;
8191
}
8292

8393
ucontact_t **sanitize_contacts(ucontact_t *contacts, int flags, int max_latency)

serialize.c

+12-5
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ int init_serialization(void)
7272
* contact is the last one in its priority class. Finally, removes
7373
* all branches from destination set.
7474
*/
75-
int serialize_branches(struct sip_msg *msg, int clean_before )
75+
int serialize_branches(struct sip_msg *msg, int clean_before, int keep_order)
7676
{
7777
static struct serial_contact contacts[MAX_BRANCHES];
7878
int n, last, first, i, prev;
@@ -100,7 +100,7 @@ int serialize_branches(struct sip_msg *msg, int clean_before )
100100
break;
101101
}
102102

103-
if (branch.s == 0) {
103+
if (branch.s == 0 && !keep_order) {
104104
LM_DBG("nothing to do - all same q!\n");
105105
return 0;
106106
}
@@ -185,8 +185,15 @@ int serialize_branches(struct sip_msg *msg, int clean_before )
185185
contacts[n].enc_info = enc_info;
186186
contacts[n].q = q;
187187

188-
/* insert based on q */
189-
for (i = first, prev=-1; i != -1 && contacts[i].q < q; prev=i,i = contacts[i].next);
188+
if (keep_order) {
189+
contacts[n].next = first;
190+
first = n++;
191+
continue;
192+
}
193+
194+
/* insert based on ascending q values, so add_avp() reverses them */
195+
for (i = first, prev = -1;
196+
i != -1 && contacts[i].q < q; prev = i ,i = contacts[i].next);
190197

191198
if (i == -1) {
192199
/* append */
@@ -209,7 +216,7 @@ int serialize_branches(struct sip_msg *msg, int clean_before )
209216

210217
/* Assign values for q_flags */
211218
for (i = first; contacts[i].next != -1; i = contacts[i].next) {
212-
if (contacts[i].q < contacts[contacts[i].next].q)
219+
if (keep_order || contacts[i].q < contacts[contacts[i].next].q)
213220
contacts[contacts[i].next].q_flag = Q_FLAG;
214221
else
215222
contacts[contacts[i].next].q_flag = 0;

serialize.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ int init_serialization();
4242
/*! \brief converts the destination set (for parallel forking) into AVPS used
4343
* for serial forking.
4444
*/
45-
int serialize_branches(struct sip_msg *msg, int clean_before );
45+
int serialize_branches(struct sip_msg *msg, int clean_before, int keep_order);
4646

4747

4848
/*! \brief gets the next branches for serial forking

0 commit comments

Comments
 (0)