Commit 22cd6563 authored by Simon Morlat's avatar Simon Morlat
Browse files

implement system random port selection

parent c419b7cb
......@@ -123,7 +123,7 @@ belle_sip_error_code belle_sip_uri_marshal(const belle_sip_uri_t* uri, char* buf
belle_sip_warning("no host found in this uri");
}
if (uri->port>0) {
if (uri->port!=0) {
error=belle_sip_snprintf(buff,buff_size,offset,":%i",uri->port);
if (error!=BELLE_SIP_OK) return error;
}
......
......@@ -58,22 +58,24 @@ BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(belle_sip_udp_listening_point_t)
BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END
static belle_sip_socket_t create_udp_socket(const char *addr, int port, int *family){
static belle_sip_socket_t create_udp_socket(const char *addr, int *port, int *family){
struct addrinfo hints={0};
struct addrinfo *res=NULL;
int err;
belle_sip_socket_t sock;
char portnum[10];
int optval=1;
if (*port==-1) *port=0; /*random port for bind()*/
snprintf(portnum,sizeof(portnum),"%i",port);
snprintf(portnum,sizeof(portnum),"%i",*port);
hints.ai_family=AF_UNSPEC;
hints.ai_socktype=SOCK_DGRAM;
hints.ai_protocol=IPPROTO_UDP;
hints.ai_flags=AI_NUMERICSERV;
err=getaddrinfo(addr,portnum,&hints,&res);
if (err!=0){
belle_sip_error("getaddrinfo() failed for %s port %i: %s",addr,port,gai_strerror(err));
belle_sip_error("getaddrinfo() failed for %s port %i: %s",addr,*port,gai_strerror(err));
return -1;
}
*family=res->ai_family;
......@@ -91,23 +93,37 @@ static belle_sip_socket_t create_udp_socket(const char *addr, int port, int *fam
err=bind(sock,res->ai_addr,res->ai_addrlen);
if (err==-1){
belle_sip_error("udp bind() failed for %s port %i: %s",addr,port,belle_sip_get_socket_error_string());
belle_sip_error("udp bind() failed for %s port %i: %s",addr,*port,belle_sip_get_socket_error_string());
close_socket(sock);
freeaddrinfo(res);
return -1;
}
freeaddrinfo(res);
if (*port==0){
struct sockaddr_storage saddr;
socklen_t saddr_len=sizeof(saddr);
err=getsockname(sock,(struct sockaddr*)&saddr,&saddr_len);
if (err==0){
err=getnameinfo((struct sockaddr*)&saddr,saddr_len,NULL,0,portnum,sizeof(portnum),NI_NUMERICSERV|NI_NUMERICHOST);
if (err==0){
*port=atoi(portnum);
belle_sip_message("Random UDP port is %i",*port);
}else belle_sip_error("udp bind failed, getnameinfo(): %s",gai_strerror(err));
}else belle_sip_error("udp bind failed, getsockname(): %s",belle_sip_get_socket_error_string());
}
return sock;
}
static int on_udp_data(belle_sip_udp_listening_point_t *lp, unsigned int events);
static int belle_sip_udp_listening_point_init_socket(belle_sip_udp_listening_point_t *lp){
int port=belle_sip_uri_get_listening_port(((belle_sip_listening_point_t*)lp)->listening_uri);
lp->sock=create_udp_socket(belle_sip_uri_get_host(((belle_sip_listening_point_t*)lp)->listening_uri)
,belle_sip_uri_get_port(((belle_sip_listening_point_t*)lp)->listening_uri),&lp->base.ai_family);
,&port,&lp->base.ai_family);
if (lp->sock==(belle_sip_socket_t)-1){
return -1;
}
belle_sip_uri_set_port(((belle_sip_listening_point_t*)lp)->listening_uri,port);
if (lp->base.stack->dscp)
belle_sip_socket_set_dscp(lp->sock,lp->base.ai_family,lp->base.stack->dscp);
lp->source=belle_sip_socket_source_new((belle_sip_source_func_t)on_udp_data,lp,lp->sock,BELLE_SIP_EVENT_READ,-1);
......
......@@ -642,6 +642,33 @@ static int register_test_with_interfaces(const char *transport, const char *clie
return ret;
}
static int register_test_with_random_port(const char *transport, const char *client_ip, const char *server_ip, int connection_family) {
int ret=0;
belle_sip_listener_callbacks_t client_callbacks;
belle_sip_listener_callbacks_t server_callbacks;
endpoint_t* client,*server;
memset(&client_callbacks,0,sizeof(belle_sip_listener_callbacks_t));
memset(&server_callbacks,0,sizeof(belle_sip_listener_callbacks_t));
client_callbacks.process_response_event=client_process_response_event;
client_callbacks.process_auth_requested=client_process_auth_requested;
server_callbacks.process_request_event=server_process_request_event;
client = create_endpoint(client_ip,-1,transport,&client_callbacks);
client->connection_family=connection_family;
client->register_count=1;
server = create_endpoint(server_ip,6788,transport,&server_callbacks);
server->expire_in_contact=client->expire_in_contact=0;
server->auth=none;
if (client->lp==NULL || server->lp==NULL){
belle_sip_warning("Cannot check ipv6 because host has no ipv6 support.");
ret=-1;
}else register_base(client,server);
destroy_endpoint(client);
destroy_endpoint(server);
return ret;
}
static void register_test_ipv6_to_ipv4(void){
if (!belle_sip_tester_ipv6_available()){
belle_sip_warning("Test skipped, IPv6 connectivity not available.");
......@@ -706,6 +733,18 @@ static void register_tcp_test_ipv6_to_ipv6_with_ipv6(void){
register_test_with_interfaces("tcp","::0","::0",AF_INET6);
}
static void register_udp_test_ipv4_random_port(void){
register_test_with_random_port("udp","0.0.0.0","0.0.0.0",AF_INET);
}
static void register_udp_test_ipv6_random_port(void){
if (!belle_sip_tester_ipv6_available()){
belle_sip_warning("Test skipped, IPv6 connectivity not available.");
return;
}
register_test_with_random_port("udp","::0","0.0.0.0",AF_INET);
}
static void simple_publish() {
belle_sip_header_content_type_t* content_type=belle_sip_header_content_type_create("application","pidf+xml");
refresher_base_with_param_and_body("PUBLISH",FALSE,TRUE,FALSE, content_type,publish_body);
......@@ -735,7 +774,9 @@ test_t refresher_tests[] = {
{ "REGISTER TCP from ipv6 to ipv4", register_tcp_test_ipv6_to_ipv4 },
{ "REGISTER TCP from ipv4 to ipv6", register_tcp_test_ipv4_to_ipv6 },
{ "REGISTER TCP from ipv6 to ipv6 with ipv4", register_tcp_test_ipv6_to_ipv6_with_ipv4 },
{ "REGISTER TCP from ipv6 to ipv6 with ipv6", register_tcp_test_ipv6_to_ipv6_with_ipv6 }
{ "REGISTER TCP from ipv6 to ipv6 with ipv6", register_tcp_test_ipv6_to_ipv6_with_ipv6 },
{ "REGISTER UDP from random port using AF_INET", register_udp_test_ipv4_random_port },
{ "REGISTER UDP from random port using AF_INET6", register_udp_test_ipv6_random_port },
};
test_suite_t refresher_test_suite = {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment