/* Successful IPv6 AAAA query */ static void ipv6_aaaa_query(void) { struct addrinfo *ai; int timeout; endpoint_t *client; if (!belle_sip_tester_ipv6_available()){ belle_sip_warning("Test skipped, IPv6 connectivity not available."); return; } client = create_endpoint(); BC_ASSERT_PTR_NOT_NULL_FATAL(client); timeout = belle_sip_stack_get_dns_timeout(client->stack); client->resolver_ctx = belle_sip_stack_resolve_a(client->stack, IPV6_SIP_DOMAIN, SIP_PORT, AF_INET6, a_resolve_done, client); BC_ASSERT_PTR_NOT_NULL(client->resolver_ctx); BC_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout)); BC_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL); if (client->ai_list) { struct addrinfo *next; struct sockaddr_in6 *sock_in6 = (struct sockaddr_in6 *)client->ai_list->ai_addr; int ntohsi = ntohs(sock_in6->sin6_port); BC_ASSERT_EQUAL(ntohsi, SIP_PORT, int, "%d"); /*the IPv6 address shall return first, and must be a real ipv6 address*/ BC_ASSERT_TRUE(client->ai_list->ai_family==AF_INET6); BC_ASSERT_FALSE(IN6_IS_ADDR_V4MAPPED(&sock_in6->sin6_addr)); ai = belle_sip_ip_address_to_addrinfo(AF_INET6, IPV6_SIP_IP, SIP_PORT); BC_ASSERT_PTR_NOT_NULL(ai); if (ai) { struct in6_addr *ipv6_address = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; int i; for (i = 0; i < 8; i++) { BC_ASSERT_EQUAL(sock_in6->sin6_addr.s6_addr[i], ipv6_address->s6_addr[i], int, "%d"); } belle_sip_freeaddrinfo(ai); } next=client->ai_list->ai_next; BC_ASSERT_PTR_NOT_NULL(next); if (next){ int ntohsi = ntohs(sock_in6->sin6_port); sock_in6 = (struct sockaddr_in6 *)next->ai_addr; BC_ASSERT_TRUE(next->ai_family==AF_INET6); BC_ASSERT_TRUE(IN6_IS_ADDR_V4MAPPED(&sock_in6->sin6_addr)); BC_ASSERT_EQUAL(ntohsi, SIP_PORT, int, "%d"); ai = belle_sip_ip_address_to_addrinfo(AF_INET6, IPV6_SIP_IPV4, SIP_PORT); BC_ASSERT_PTR_NOT_NULL(ai); if (ai) { struct in6_addr *ipv6_address = &((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr; int i; for (i = 0; i < 8; i++) { BC_ASSERT_EQUAL(sock_in6->sin6_addr.s6_addr[i], ipv6_address->s6_addr[i], int, "%d"); } belle_sip_freeaddrinfo(ai); } } } destroy_endpoint(client); }
static void ipv4_and_ipv6_dns_server(void) { struct addrinfo *ai; int timeout; endpoint_t *client; const char *nameservers[]={ "8.8.8.8", "2a01:e00::2", NULL }; if (!belle_sip_tester_ipv6_available()){ belle_sip_warning("Test skipped, IPv6 connectivity not available."); return; } client = create_endpoint(); CU_ASSERT_PTR_NOT_NULL_FATAL(client); timeout = belle_sip_stack_get_dns_timeout(client->stack); set_custom_resolv_conf(client->stack,nameservers); client->resolver_ctx = belle_sip_stack_resolve_a(client->stack, IPV4_SIP_DOMAIN, SIP_PORT, AF_INET, a_resolve_done, client); CU_ASSERT_NOT_EQUAL(client->resolver_ctx, NULL); CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout)); CU_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL); if (client->ai_list) { struct sockaddr_in *sock_in = (struct sockaddr_in *)client->ai_list->ai_addr; CU_ASSERT_EQUAL(ntohs(sock_in->sin_port), SIP_PORT); ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT); if (ai) { CU_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr); belle_sip_freeaddrinfo(ai); } } destroy_endpoint(client); }
static void dns_fallback(void) { struct addrinfo *ai; int timeout; endpoint_t *client = create_endpoint(); const char *nameservers[]={ "94.23.19.176", /*linphone.org ; this is not a name server, it will not respond*/ "8.8.8.8", /* public nameserver, should work*/ NULL }; CU_ASSERT_PTR_NOT_NULL_FATAL(client); timeout = belle_sip_stack_get_dns_timeout(client->stack); set_custom_resolv_conf(client->stack,nameservers); client->resolver_ctx = belle_sip_stack_resolve_a(client->stack, IPV4_SIP_DOMAIN, SIP_PORT, AF_INET, a_resolve_done, client); CU_ASSERT_NOT_EQUAL(client->resolver_ctx, NULL); CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout)); CU_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL); if (client->ai_list) { struct sockaddr_in *sock_in = (struct sockaddr_in *)client->ai_list->ai_addr; CU_ASSERT_EQUAL(ntohs(sock_in->sin_port), SIP_PORT); ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT); if (ai) { CU_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr); belle_sip_freeaddrinfo(ai); } } destroy_endpoint(client); }
/*constructor for channels creating an outgoing connection * bindip local ip address to bind on, typically 0.0.0.0 or ::0 * 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. */ 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:*/ belle_sip_channel_set_socket(obj,-1,NULL); /*then initialize members*/ obj->ai_family=AF_INET; obj->peer_cname=peer_cname ? belle_sip_strdup(peer_cname) : NULL; obj->peer_name=belle_sip_strdup(peername); obj->peer_port=peer_port; obj->stack=stack; if (bindip){ if (strcmp(bindip,"::0")!=0 && strcmp(bindip,"0.0.0.0")!=0) obj->local_ip=belle_sip_strdup(bindip); if (strchr(bindip,':')!=NULL) obj->ai_family=AF_INET6; } obj->local_port=localport; obj->simulated_recv_return=1;/*not set*/ if (peername){ /*check if we are given a real dns name or just an ip address*/ struct addrinfo *ai=belle_sip_ip_address_to_addrinfo(AF_UNSPEC,peername,peer_port); if (ai) freeaddrinfo(ai); else obj->has_name=TRUE; } belle_sip_channel_input_stream_reset(&obj->input_stream); update_inactivity_timer(obj,FALSE); }
/*constructor for channels created by incoming connections*/ void belle_sip_channel_init_with_addr(belle_sip_channel_t *obj, belle_sip_stack_t *stack, const struct sockaddr *peer_addr, socklen_t addrlen){ char remoteip[64]; struct addrinfo ai; int peer_port; memset(&ai,0,sizeof(ai)); ai.ai_family=peer_addr->sa_family; ai.ai_addr=(struct sockaddr*)peer_addr; ai.ai_addrlen=addrlen; belle_sip_addrinfo_to_ip(&ai,remoteip,sizeof(remoteip),&peer_port); belle_sip_channel_init(obj,stack,NULL,0,NULL,remoteip,peer_port); obj->peer_list=obj->current_peer=belle_sip_ip_address_to_addrinfo(ai.ai_family, obj->peer_name,obj->peer_port); obj->ai_family=ai.ai_family; }
int liblinphone_tester_ipv6_available(void){ struct addrinfo *ai=belle_sip_ip_address_to_addrinfo(AF_INET6,"2a01:e00::2",53); if (ai){ struct sockaddr_storage ss; struct addrinfo src; socklen_t slen=sizeof(ss); char localip[128]; int port=0; belle_sip_get_src_addr_for(ai->ai_addr,ai->ai_addrlen,(struct sockaddr*) &ss,&slen,4444); src.ai_addr=(struct sockaddr*) &ss; src.ai_addrlen=slen; belle_sip_addrinfo_to_ip(&src,localip, sizeof(localip),&port); freeaddrinfo(ai); return strcmp(localip,"::1")!=0; } return FALSE; }
/* No query needed because already resolved */ static void no_query_needed(void) { struct addrinfo *ai; endpoint_t *client = create_endpoint(); CU_ASSERT_PTR_NOT_NULL_FATAL(client); client->resolver_ctx = belle_sip_stack_resolve(client->stack, "udp", IPV4_SIP_IP, SIP_PORT, AF_INET, a_resolve_done, client); CU_ASSERT_EQUAL(client->resolver_ctx, NULL); CU_ASSERT_TRUE(client->resolve_done); CU_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL); if (client->ai_list) { struct sockaddr_in *sock_in = (struct sockaddr_in *)client->ai_list->ai_addr; CU_ASSERT_EQUAL(ntohs(sock_in->sin_port), SIP_PORT); ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT); if (ai) { CU_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr); belle_sip_freeaddrinfo(ai); } } destroy_endpoint(client); }
/* Successful SRV query with no result + A query */ static void srv_a_query_no_srv_result(void) { struct addrinfo *ai; int timeout; endpoint_t *client = create_endpoint(); CU_ASSERT_PTR_NOT_NULL_FATAL(client); timeout = belle_sip_stack_get_dns_timeout(client->stack); client->resolver_ctx = belle_sip_stack_resolve(client->stack, "udp", IPV4_SIP_DOMAIN, SIP_PORT, AF_INET, a_resolve_done, client); CU_ASSERT_NOT_EQUAL(client->resolver_ctx, NULL); CU_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout)); CU_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL); if (client->ai_list) { struct sockaddr_in *sock_in = (struct sockaddr_in *)client->ai_list->ai_addr; CU_ASSERT_EQUAL(ntohs(sock_in->sin_port), SIP_PORT); ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_SIP_IP, SIP_PORT); if (ai) { CU_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr); belle_sip_freeaddrinfo(ai); } } destroy_endpoint(client); }
/*This tests the recursion of dns.c*/ static void ipv4_cname_a_query(void) { struct addrinfo *ai; int timeout; endpoint_t *client = create_endpoint(); BC_ASSERT_PTR_NOT_NULL_FATAL(client); timeout = belle_sip_stack_get_dns_timeout(client->stack); client->resolver_ctx = belle_sip_stack_resolve_a(client->stack, IPV4_CNAME, SIP_PORT, AF_INET, a_resolve_done, client); BC_ASSERT_PTR_NOT_NULL(client->resolver_ctx); BC_ASSERT_TRUE(wait_for(client->stack, &client->resolve_done, 1, timeout)); BC_ASSERT_PTR_NOT_EQUAL(client->ai_list, NULL); if (client->ai_list) { struct sockaddr_in *sock_in = (struct sockaddr_in *)client->ai_list->ai_addr; int ntohsi = (int)ntohs(sock_in->sin_port); BC_ASSERT_EQUAL(ntohsi, SIP_PORT, int, "%d"); ai = belle_sip_ip_address_to_addrinfo(AF_INET, IPV4_CNAME_IP, SIP_PORT); if (ai) { BC_ASSERT_EQUAL(sock_in->sin_addr.s_addr, ((struct sockaddr_in *)ai->ai_addr)->sin_addr.s_addr, int, "%d"); belle_sip_freeaddrinfo(ai); } } destroy_endpoint(client); }