Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
B
belle-sip
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
4
Issues
4
List
Board
Labels
Milestones
Merge Requests
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
External Wiki
External Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
BC
public
belle-sip
Commits
6688941c
Commit
6688941c
authored
May 05, 2014
by
Simon Morlat
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
implement DNS SRV weight selection
parent
dd24b7b4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
75 additions
and
1 deletion
+75
-1
belle_sip_resolver.c
src/belle_sip_resolver.c
+75
-1
No files found.
src/belle_sip_resolver.c
View file @
6688941c
...
...
@@ -44,11 +44,14 @@ struct belle_sip_dns_srv{
unsigned
short
priority
;
unsigned
short
weight
;
unsigned
short
port
;
unsigned
char
a_done
;
unsigned
char
pad
;
int
cumulative_weight
;
/*used only temporarily*/
char
*
target
;
belle_sip_combined_resolver_context_t
*
root_resolver
;
/* used internally to combine SRV and A queries*/
belle_sip_resolver_context_t
*
a_resolver
;
/* used internally to combine SRV and A queries*/
struct
addrinfo
*
a_results
;
/* used internally to combine SRV and A queries*/
unsigned
char
a_done
;
};
static
void
belle_sip_dns_srv_destroy
(
belle_sip_dns_srv_t
*
obj
){
...
...
@@ -286,11 +289,82 @@ static int srv_compare_prio(const void *psrv1, const void *psrv2){
return
1
;
}
/*
* see https://www.ietf.org/rfc/rfc2782.txt
* 0 weighted must just appear first.
**/
static
int
srv_sort_weight
(
const
void
*
psrv1
,
const
void
*
psrv2
){
belle_sip_dns_srv_t
*
srv1
=
(
belle_sip_dns_srv_t
*
)
psrv1
;
if
(
srv1
->
weight
==
0
)
return
-
1
;
return
1
;
}
static
belle_sip_dns_srv_t
*
srv_elect_one
(
belle_sip_list_t
*
srv_list
){
int
sum
=
0
;
belle_sip_list_t
*
elem
;
belle_sip_dns_srv_t
*
srv
;
int
rand_number
;
for
(
elem
=
srv_list
;
elem
!=
NULL
;
elem
=
elem
->
next
){
srv
=
(
belle_sip_dns_srv_t
*
)
elem
->
data
;
sum
+=
srv
->
weight
;
srv
->
cumulative_weight
=
sum
;
}
/*no weights given, return the first one*/
if
(
sum
==
0
)
return
(
belle_sip_dns_srv_t
*
)
srv_list
->
data
;
rand_number
=
belle_sip_random
()
%
sum
;
/*random number choosen in the range of the sum of weights*/
for
(
elem
=
srv_list
;
elem
!=
NULL
;
elem
=
elem
->
next
){
srv
=
(
belle_sip_dns_srv_t
*
)
elem
->
data
;
if
(
rand_number
>=
srv
->
cumulative_weight
)
return
srv
;
}
/*we should not reach this line*/
belle_sip_warning
(
"srv_elect_one(): should not happen."
);
return
(
belle_sip_dns_srv_t
*
)
srv_list
->
data
;
}
/*
* this function will return a list of SRV, with only one SRV record per priority.
*/
static
belle_sip_list_t
*
srv_select_by_weight
(
belle_sip_list_t
*
srv_list
){
belle_sip_list_t
*
same_prio
=
NULL
;
belle_sip_list_t
*
elem
;
belle_sip_dns_srv_t
*
prev_srv
=
NULL
;
belle_sip_list_t
*
result
=
NULL
;
for
(
elem
=
srv_list
;
elem
!=
NULL
;
elem
=
elem
->
next
){
belle_sip_dns_srv_t
*
srv
=
(
belle_sip_dns_srv_t
*
)
elem
->
data
;
if
(
prev_srv
){
if
(
prev_srv
->
priority
==
srv
->
priority
){
if
(
!
same_prio
){
same_prio
=
belle_sip_list_append
(
same_prio
,
prev_srv
);
}
same_prio
=
belle_sip_list_insert_sorted
(
same_prio
,
srv
,
srv_sort_weight
);
}
else
{
if
(
same_prio
){
result
=
belle_sip_list_append
(
result
,
belle_sip_object_ref
(
srv_elect_one
(
same_prio
)));
same_prio
=
NULL
;
}
}
}
prev_srv
=
srv
;
}
if
(
same_prio
){
result
=
belle_sip_list_append
(
result
,
belle_sip_object_ref
(
srv_elect_one
(
same_prio
)));
}
if
(
result
){
belle_sip_list_free_with_data
(
srv_list
,
belle_sip_object_unref
);
return
result
;
}
return
srv_list
;
/*no weight election was necessary, return original list*/
}
static
void
notify_results
(
belle_sip_simple_resolver_context_t
*
ctx
){
ctx
->
base
.
done
=
TRUE
;
if
((
ctx
->
type
==
DNS_T_A
)
||
(
ctx
->
type
==
DNS_T_AAAA
))
{
ctx
->
cb
(
ctx
->
cb_data
,
ctx
->
name
,
ctx
->
ai_list
);
}
else
if
(
ctx
->
type
==
DNS_T_SRV
)
{
ctx
->
srv_list
=
srv_select_by_weight
(
ctx
->
srv_list
);
ctx
->
srv_cb
(
ctx
->
srv_cb_data
,
ctx
->
name
,
ctx
->
srv_list
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment