Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
belle-sip
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
41666379
Commit
41666379
authored
Aug 23, 2018
by
Simon Morlat
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'feature/resolver-improvements'
parents
0b57292c
dbc0781b
Pipeline
#274
failed with stage
in 0 seconds
Changes
9
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
227 additions
and
71 deletions
+227
-71
resolver.h
include/belle-sip/resolver.h
+20
-3
types.h
include/belle-sip/types.h
+2
-1
belle_sip_internal.h
src/belle_sip_internal.h
+1
-0
belle_sip_resolver.c
src/belle_sip_resolver.c
+125
-22
channel.c
src/channel.c
+49
-21
channel.h
src/channel.h
+7
-4
tls_channel.c
src/transports/tls_channel.c
+4
-3
belle_sip_resolver_tester.c
tester/belle_sip_resolver_tester.c
+15
-11
resolve.c
tester/resolve.c
+4
-6
No files found.
include/belle-sip/resolver.h
View file @
41666379
...
...
@@ -25,6 +25,9 @@ typedef struct belle_sip_dns_srv belle_sip_dns_srv_t;
typedef
struct
belle_sip_resolver_context
belle_sip_resolver_context_t
;
#define BELLE_SIP_RESOLVER_CONTEXT(obj) BELLE_SIP_CAST(obj,belle_sip_resolver_context_t)
typedef
struct
belle_sip_resolver_results
belle_sip_resolver_results_t
;
#define BELLE_SIP_RESOLVER_RESULTS(obj) BELLE_SIP_CAST(obj,belle_sip_resolver_results_t)
/**
* Callback prototype for asynchronous DNS SRV resolution.
* The srv_list contains struct dns_srv elements that must be taken and (possibly later) freed by the callee, using belle_sip_free().
...
...
@@ -33,10 +36,10 @@ typedef void (*belle_sip_resolver_srv_callback_t)(void *data, const char *name,
/**
* Callback prototype for asynchronous DNS A and AAAA resolution.
* The
ai_list contains addrinfo elements that must be taken and (possibly later) freed by the callee, using freeaddrinfo()
.
* The
se elements are linked by their ai_next field
.
* The
'results' object must be acquired (ref'd) in order for being accessed outside of the callback
.
* The
results object provides SRV records list and addrinfo list
.
**/
typedef
void
(
*
belle_sip_resolver_callback_t
)(
void
*
data
,
const
char
*
name
,
struct
addrinfo
*
ai_list
,
uint32_t
ttl
);
typedef
void
(
*
belle_sip_resolver_callback_t
)(
void
*
data
,
belle_sip_resolver_results_t
*
results
);
BELLE_SIP_BEGIN_DECLS
...
...
@@ -49,6 +52,20 @@ BELLESIP_EXPORT unsigned short belle_sip_dns_srv_get_weight(const belle_sip_dns_
BELLESIP_EXPORT
unsigned
short
belle_sip_dns_srv_get_port
(
const
belle_sip_dns_srv_t
*
obj
);
/**
* Find the belle_sip_dns_srv_t object associated with a particular addrinfo.
* The srv_list and the addrinfo must be the ones given by the belle_sip_resolver_callback_t callback invoked consecutively to a call
* to belle_sip_stack_resolve().
**/
BELLESIP_EXPORT
const
belle_sip_dns_srv_t
*
belle_sip_resolver_results_get_srv_from_addrinfo
(
const
belle_sip_resolver_results_t
*
obj
,
const
struct
addrinfo
*
ai
);
BELLESIP_EXPORT
const
bctbx_list_t
*
belle_sip_resolver_results_get_srv_records
(
const
belle_sip_resolver_results_t
*
obj
);
BELLESIP_EXPORT
const
struct
addrinfo
*
belle_sip_resolver_results_get_addrinfos
(
const
belle_sip_resolver_results_t
*
obj
);
BELLESIP_EXPORT
int
belle_sip_resolver_results_get_ttl
(
const
belle_sip_resolver_results_t
*
obj
);
BELLESIP_EXPORT
const
char
*
belle_sip_resolver_results_get_name
(
const
belle_sip_resolver_results_t
*
obj
);
/**
* Asynchronously performs DNS SRV followed A/AAAA query. Automatically fallbacks to A/AAAA if SRV isn't found.
...
...
include/belle-sip/types.h
View file @
41666379
...
...
@@ -149,7 +149,8 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID
(
belle_sip_header_accept_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_header_reason_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_header_authentication_info_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_mdns_register_t
)
BELLE_SIP_TYPE_ID
(
belle_sip_mdns_register_t
),
BELLE_SIP_TYPE_ID
(
belle_sip_resolver_results_t
)
BELLE_SIP_DECLARE_TYPES_END
...
...
src/belle_sip_internal.h
View file @
41666379
...
...
@@ -234,6 +234,7 @@ BELLE_SIP_DECLARE_VPTR(belle_sip_header_authentication_info_t);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_mdns_source_t
);
BELLE_SIP_DECLARE_VPTR
(
belle_sip_mdns_register_t
);
#endif
BELLE_SIP_DECLARE_VPTR
(
belle_sip_resolver_results_t
);
BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN
(
belle_sip_resolver_context_t
,
belle_sip_source_t
)
...
...
src/belle_sip_resolver.c
View file @
41666379
This diff is collapsed.
Click to expand it.
src/channel.c
View file @
41666379
...
...
@@ -109,7 +109,6 @@ static size_t belle_sip_channel_input_stream_get_buff_length(belle_sip_channel_i
static
void
belle_sip_channel_destroy
(
belle_sip_channel_t
*
obj
){
belle_sip_channel_input_stream_reset
(
&
obj
->
input_stream
);
if
(
obj
->
peer_list
)
bctbx_freeaddrinfo
(
obj
->
peer_list
);
if
(
obj
->
peer_cname
)
belle_sip_free
(
obj
->
peer_cname
);
belle_sip_free
(
obj
->
peer_name
);
if
(
obj
->
local_ip
)
belle_sip_free
(
obj
->
local_ip
);
...
...
@@ -120,6 +119,8 @@ static void belle_sip_channel_destroy(belle_sip_channel_t *obj){
belle_sip_resolver_context_cancel
(
obj
->
resolver_ctx
);
belle_sip_object_unref
(
obj
->
resolver_ctx
);
}
SET_OBJECT_PROPERTY
(
obj
,
resolver_results
,
NULL
);
if
(
obj
->
static_peer_list
)
bctbx_freeaddrinfo
(
obj
->
static_peer_list
);
if
(
obj
->
inactivity_timer
){
belle_sip_main_loop_remove_source
(
obj
->
stack
->
ml
,
obj
->
inactivity_timer
);
belle_sip_object_unref
(
obj
->
inactivity_timer
);
...
...
@@ -745,7 +746,7 @@ static void update_inactivity_timer(belle_sip_channel_t *obj, int from_recv){
* locaport locaport to use for binding, can be set to 0 if port doesn't matter
* peer_cname canonical name of remote host, used for TLS verification
* peername peer's hostname, either ip address or DNS name
* pee_port peer's port to connect to.
* pee
r
_port peer's port to connect to.
*/
void
belle_sip_channel_init
(
belle_sip_channel_t
*
obj
,
belle_sip_stack_t
*
stack
,
const
char
*
bindip
,
int
localport
,
const
char
*
peer_cname
,
const
char
*
peername
,
int
peer_port
){
/*to initialize our base class:*/
...
...
@@ -787,7 +788,7 @@ void belle_sip_channel_init_with_addr(belle_sip_channel_t *obj, belle_sip_stack_
ai
.
ai_addrlen
=
addrlen
;
bctbx_addrinfo_to_ip_address
(
&
ai
,
remoteip
,
sizeof
(
remoteip
),
&
peer_port
);
belle_sip_channel_init
(
obj
,
stack
,
bindip
,
localport
,
NULL
,
remoteip
,
peer_port
);
obj
->
peer_list
=
obj
->
current_peer
=
bctbx_ip_address_to_addrinfo
(
ai
.
ai_family
,
ai
.
ai_socktype
,
obj
->
peer_name
,
obj
->
peer_port
);
obj
->
peer_list
=
obj
->
current_peer
=
obj
->
static_peer_list
=
bctbx_ip_address_to_addrinfo
(
ai
.
ai_family
,
ai
.
ai_socktype
,
obj
->
peer_name
,
obj
->
peer_port
);
obj
->
ai_family
=
ai
.
ai_family
;
}
...
...
@@ -835,7 +836,8 @@ void belle_sip_channel_remove_listener(belle_sip_channel_t *obj, belle_sip_chann
}
int
belle_sip_channel_matches
(
const
belle_sip_channel_t
*
obj
,
const
belle_sip_hop_t
*
hop
,
const
struct
addrinfo
*
addr
){
if
(
hop
&&
strcmp
(
hop
->
host
,
obj
->
peer_name
)
==
0
&&
(
hop
->
port
==
obj
->
peer_port
||
obj
->
srv_overrides_port
)){
if
(
hop
&&
(
strcmp
(
hop
->
host
,
obj
->
peer_name
)
==
0
||
(
obj
->
current_peer_cname
&&
strcmp
(
hop
->
host
,
obj
->
current_peer_cname
)
==
0
))
&&
(
hop
->
port
==
obj
->
peer_port
||
obj
->
srv_overrides_port
)){
if
(
hop
->
cname
&&
obj
->
peer_cname
&&
strcmp
(
hop
->
cname
,
obj
->
peer_cname
)
!=
0
)
return
0
;
/*cname mismatch*/
return
1
;
...
...
@@ -1000,13 +1002,26 @@ static void channel_connect_next(belle_sip_channel_t *obj){
belle_sip_object_unref
(
obj
);
}
static
void
channel_set_current_peer
(
belle_sip_channel_t
*
obj
,
const
struct
addrinfo
*
ai
){
if
(
obj
->
resolver_results
){
const
belle_sip_dns_srv_t
*
srv
=
belle_sip_resolver_results_get_srv_from_addrinfo
(
obj
->
resolver_results
,
ai
);
obj
->
current_peer_cname
=
srv
?
belle_sip_dns_srv_get_target
(
srv
)
:
NULL
;
if
(
obj
->
current_peer_cname
){
belle_sip_message
(
"channel[%p]: current peer hostname is [%s]."
,
obj
,
obj
->
current_peer_cname
);
}
}
else
{
obj
->
current_peer_cname
=
NULL
;
}
obj
->
current_peer
=
ai
;
}
static
void
belle_sip_channel_handle_error
(
belle_sip_channel_t
*
obj
){
if
(
obj
->
state
!=
BELLE_SIP_CHANNEL_READY
||
obj
->
soft_error
){
/* Previous connection attempts were failed (channel could not get ready) OR soft error reported*/
obj
->
soft_error
=
FALSE
;
/* See if you can retry on an alternate ip address.*/
if
(
obj
->
current_peer
&&
obj
->
current_peer
->
ai_next
){
/*obj->current_peer may be null in case of dns error*/
obj
->
current_peer
=
obj
->
current_peer
->
ai_next
;
channel_set_current_peer
(
obj
,
obj
->
current_peer
->
ai_next
)
;
channel_set_state
(
obj
,
BELLE_SIP_CHANNEL_RETRY
);
belle_sip_channel_close
(
obj
);
belle_sip_main_loop_do_later
(
obj
->
stack
->
ml
,(
belle_sip_callback_t
)
channel_connect_next
,
belle_sip_object_ref
(
obj
));
...
...
@@ -1440,50 +1455,63 @@ static int channel_dns_ttl_timeout(void *data, unsigned int event) {
return
BELLE_SIP_STOP
;
}
static
bool_t
addrinfo_in_list
(
const
struct
addrinfo
*
ai
,
const
struct
addrinfo
*
list
)
{
/* returns the addrinfo from list that matches 'ai' in terms of content*/
static
const
struct
addrinfo
*
addrinfo_in_list
(
const
struct
addrinfo
*
ai
,
const
struct
addrinfo
*
list
)
{
const
struct
addrinfo
*
item
=
list
;
bool_t
in_list
=
FALSE
;
while
(
item
!=
NULL
)
{
if
((
ai
->
ai_family
==
item
->
ai_family
)
&&
(
bctbx_sockaddr_equals
(
ai
->
ai_addr
,
item
->
ai_addr
)))
{
in_list
=
TRUE
;
break
;
return
item
;
}
item
=
item
->
ai_next
;
}
return
in_list
;
return
NULL
;
}
static
bool_t
addrinfo_is_first
(
const
struct
addrinfo
*
ai
,
const
struct
addrinfo
*
list
)
{
/* returns the first addrinfo from list, if it is matching 'ai' in terms content*/
static
const
struct
addrinfo
*
addrinfo_is_first
(
const
struct
addrinfo
*
ai
,
const
struct
addrinfo
*
list
)
{
if
(
list
!=
NULL
&&
(
ai
->
ai_family
==
list
->
ai_family
)
&&
(
bctbx_sockaddr_equals
(
ai
->
ai_addr
,
list
->
ai_addr
)))
return
TRUE
;
return
FALSE
;
return
list
;
return
NULL
;
}
static
void
channel_res_done
(
void
*
data
,
const
char
*
name
,
struct
addrinfo
*
ai_list
,
uint32_t
ttl
){
static
void
channel_res_done
(
void
*
data
,
belle_sip_resolver_results_t
*
results
){
belle_sip_channel_t
*
obj
=
(
belle_sip_channel_t
*
)
data
;
const
struct
addrinfo
*
ai_list
=
NULL
;
const
char
*
name
=
NULL
;
if
(
obj
->
resolver_ctx
){
belle_sip_object_unref
(
obj
->
resolver_ctx
);
obj
->
resolver_ctx
=
NULL
;
}
if
(
results
){
ai_list
=
belle_sip_resolver_results_get_addrinfos
(
results
);
SET_OBJECT_PROPERTY
(
obj
,
resolver_results
,
results
);
name
=
belle_sip_resolver_results_get_name
(
results
);
}
if
(
ai_list
){
int
ttl
=
belle_sip_resolver_results_get_ttl
(
results
);
obj
->
peer_list
=
ai_list
;
if
(
!
obj
->
current_peer
)
{
obj
->
peer_list
=
obj
->
current_peer
=
ai_list
;
channel_set_current_peer
(
obj
,
ai_list
)
;
channel_set_state
(
obj
,
BELLE_SIP_CHANNEL_RES_DONE
);
}
else
{
bool_t
check
;
const
struct
addrinfo
*
existing_peer
;
if
(
belle_sip_stack_reconnect_to_primary_asap_enabled
(
obj
->
stack
))
{
check
=
addrinfo_is_first
(
obj
->
current_peer
,
ai_list
);
existing_peer
=
addrinfo_is_first
(
obj
->
current_peer
,
ai_list
);
}
else
{
check
=
addrinfo_in_list
(
obj
->
current_peer
,
ai_list
);
existing_peer
=
addrinfo_in_list
(
obj
->
current_peer
,
ai_list
);
}
if
(
check
)
{
if
(
existing_peer
)
{
belle_sip_message
(
"channel[%p]: DNS resolution returned the currently used address, continue using it"
,
obj
);
obj
->
peer_list
=
ai_list
;
channel_set_current_peer
(
obj
,
existing_peer
)
;
channel_set_state
(
obj
,
BELLE_SIP_CHANNEL_READY
);
}
else
{
belle_sip_message
(
"channel[%p]: DNS resolution returned an address different than the one being used, reconnect to the new address"
,
obj
);
obj
->
peer_list
=
obj
->
current_peer
=
ai_list
;
channel_set_current_peer
(
obj
,
ai_list
)
;
belle_sip_channel_close
(
obj
);
belle_sip_main_loop_do_later
(
obj
->
stack
->
ml
,
(
belle_sip_callback_t
)
channel_connect_next
,
belle_sip_object_ref
(
obj
));
channel_set_state
(
obj
,
BELLE_SIP_CHANNEL_RETRY
);
...
...
src/channel.h
View file @
41666379
...
...
@@ -94,16 +94,19 @@ struct belle_sip_channel{
belle_sip_list_t
*
state_listeners
;
belle_sip_list_t
*
full_listeners
;
int
ai_family
;
char
*
peer_cname
;
char
*
peer_name
;
char
*
peer_cname
;
/* A or SRV name */
char
*
peer_name
;
/* A or SRV name */
int
peer_port
;
char
*
local_ip
;
int
local_port
;
char
*
public_ip
;
int
public_port
;
belle_sip_resolver_context_t
*
resolver_ctx
;
struct
addrinfo
*
peer_list
;
struct
addrinfo
*
current_peer
;
belle_sip_resolver_results_t
*
resolver_results
;
struct
addrinfo
*
static_peer_list
;
/*this is the addrinfo when the channel is instanciated from destination IP address directly (no dns resolution)*/
const
struct
addrinfo
*
peer_list
;
/*points to the addrinfo list in resolver_results, or to the static_peer_list*/
const
struct
addrinfo
*
current_peer
;
/*points in the currently used element in peer_list */
const
char
*
current_peer_cname
;
/*name of the host we are currently connected to. Set only in SRV case*/
belle_sip_list_t
*
outgoing_messages
;
belle_sip_message_t
*
cur_out_message
;
output_stream_state_t
out_state
;
...
...
src/transports/tls_channel.c
View file @
41666379
...
...
@@ -414,17 +414,18 @@ static int tls_channel_connect_to(belle_sip_channel_t *obj, const struct addrinf
return
-
1
;
}
static
void
http_proxy_res_done
(
void
*
data
,
const
char
*
name
,
struct
addrinfo
*
ai_list
,
uint32_t
ttl
){
static
void
http_proxy_res_done
(
void
*
data
,
belle_sip_resolver_results_t
*
results
){
belle_sip_tls_channel_t
*
obj
=
(
belle_sip_tls_channel_t
*
)
data
;
const
struct
addrinfo
*
ai_list
;
if
(
obj
->
http_proxy_resolver_ctx
){
belle_sip_object_unref
(
obj
->
http_proxy_resolver_ctx
);
obj
->
http_proxy_resolver_ctx
=
NULL
;
}
ai_list
=
belle_sip_resolver_results_get_addrinfos
(
results
);
if
(
ai_list
){
tls_channel_connect_to
((
belle_sip_channel_t
*
)
obj
,
ai_list
);
bctbx_freeaddrinfo
(
ai_list
);
}
else
{
belle_sip_error
(
"%s: DNS resolution failed for %s"
,
__FUNCTION__
,
name
);
belle_sip_error
(
"%s: DNS resolution failed for %s"
,
__FUNCTION__
,
belle_sip_resolver_results_get_name
(
results
)
);
channel_set_state
((
belle_sip_channel_t
*
)
obj
,
BELLE_SIP_CHANNEL_ERROR
);
}
}
...
...
tester/belle_sip_resolver_tester.c
View file @
41666379
...
...
@@ -41,8 +41,9 @@ typedef struct endpoint {
belle_sip_resolver_context_t
*
resolver_ctx
;
int
resolve_done
;
int
resolve_ko
;
struct
addrinfo
*
ai_list
;
belle_sip_list_t
*
srv_list
;
/**< List of struct dns_srv pointers */
bctbx_list_t
*
srv_list
;
belle_sip_resolver_results_t
*
results
;
const
struct
addrinfo
*
ai_list
;
}
endpoint_t
;
static
unsigned
int
wait_for
(
belle_sip_stack_t
*
stack
,
int
*
current_value
,
int
expected_value
,
int
timeout
)
{
...
...
@@ -68,12 +69,13 @@ static void reset_endpoint(endpoint_t *endpoint) {
endpoint
->
resolver_ctx
=
0
;
endpoint
->
resolve_done
=
0
;
endpoint
->
resolve_ko
=
0
;
if
(
endpoint
->
ai_list
!=
NULL
)
{
b
ctbx_freeaddrinfo
(
endpoint
->
ai_list
);
endpoint
->
ai_list
=
NULL
;
if
(
endpoint
->
results
)
{
b
elle_sip_object_unref
(
endpoint
->
results
);
endpoint
->
results
=
NULL
;
}
if
(
endpoint
->
srv_list
!=
NULL
)
{
belle_sip_list_free_with_data
(
endpoint
->
srv_list
,
belle_sip_object_unref
);
endpoint
->
ai_list
=
NULL
;
if
(
endpoint
->
srv_list
){
bctbx_list_free_with_data
(
endpoint
->
srv_list
,
belle_sip_object_unref
);
endpoint
->
srv_list
=
NULL
;
}
}
...
...
@@ -85,12 +87,14 @@ static void destroy_endpoint(endpoint_t *endpoint) {
belle_sip_uninit_sockets
();
}
static
void
a_resolve_done
(
void
*
data
,
const
char
*
name
,
struct
addrinfo
*
ai_list
,
uint32_t
ttl
)
{
static
void
a_resolve_done
(
void
*
data
,
belle_sip_resolver_results_t
*
results
)
{
endpoint_t
*
client
=
(
endpoint_t
*
)
data
;
BELLESIP_UNUSED
(
name
);
client
->
resolve_done
=
1
;
if
(
ai_list
)
{
client
->
ai_list
=
ai_list
;
belle_sip_object_ref
(
results
);
client
->
results
=
results
;
if
(
belle_sip_resolver_results_get_addrinfos
(
results
))
{
client
->
ai_list
=
belle_sip_resolver_results_get_addrinfos
(
results
);
client
->
resolve_done
=
1
;
}
else
client
->
resolve_ko
=
1
;
...
...
tester/resolve.c
View file @
41666379
...
...
@@ -22,23 +22,21 @@
static
belle_sip_stack_t
*
stack
;
static
void
resolver_callback
(
void
*
data
,
const
char
*
queried_name
,
struct
addrinfo
*
ai_list
,
unsigned
int
ttl
){
static
void
resolver_callback
(
void
*
data
,
belle_sip_resolver_results_t
*
results
){
int
err
;
struct
addrinfo
*
ai_it
;
const
struct
addrinfo
*
ai_it
;
char
name
[
NI_MAXHOST
];
char
port
[
NI_MAXSERV
];
const
struct
addrinfo
*
ai_list
=
belle_sip_resolver_results_get_addrinfos
(
results
);
for
(
ai_it
=
ai_list
;
ai_it
!=
NULL
;
ai_it
=
ai_it
->
ai_next
){
err
=
bctbx_getnameinfo
(
ai_it
->
ai_addr
,
ai_list
->
ai_addrlen
,
name
,
sizeof
(
name
),
port
,
sizeof
(
port
),
NI_NUMERICSERV
|
NI_NUMERICHOST
);
if
(
err
!=
0
){
fprintf
(
stderr
,
"getnameinfo error: %s"
,
gai_strerror
(
err
));
}
else
{
printf
(
"
\t
%s %s (ttl:%u)
\n
"
,
name
,
port
,
ttl
);
printf
(
"
\t
%s %s (ttl:%u)
\n
"
,
name
,
port
,
belle_sip_resolver_results_get_ttl
(
results
)
);
}
}
if
(
ai_list
){
bctbx_freeaddrinfo
(
ai_list
);
}
belle_sip_main_loop_quit
(
belle_sip_stack_get_main_loop
(
stack
));
}
...
...
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