Commit 52f45446 authored by Martti Mela's avatar Martti Mela

stun: get_nattype works partially

At least OPEN Internet case is now handled properly. More modifications to follow.

darcs-hash:20060104131334-34f17-01293336fe6de3f504754f60af1d5b2c231b6429.gz
parent 3a923186
......@@ -39,9 +39,9 @@
#include <assert.h>
#define SU_ROOT_MAGIC_T struct stun_handle_s
#define SU_ROOT_MAGIC_T struct stun_magic_t
#define SU_WAKEUP_ARG_T struct stun_handle_s
#define SU_TIMER_ARG_T struct stun_request_s
/* #define SU_TIMER_ARG_T union stun_object_u */
#include "stun.h"
#include "stun_internal.h"
......@@ -65,14 +65,35 @@ enum {
};
char const stun_nat_unknown[] = "NAT type undetermined",
stun_open_internet[] = "Open Internet",
stun_udp_blocked[] = "UDP traffic is blocked, or Server unreachable",
stun_sym_udp_fw[] = "Symmetric UDP Firewall",
stun_nat_full_cone[] = "Full-Cone NAT",
stun_nat_sym[] = "Symmetric NAT",
stun_nat_res_cone[] = "Restricted Cone NAT",
stun_nat_port_res_cone[] = "Port Restricted Cone NAT";
typedef enum stun_action_s {
stun_action_no_action,
stun_action_binding_request,
stun_action_keepalive,
stun_action_get_nattype,
stun_action_get_lifetime,
} stun_action_t;
#define CHG_IP 0x001
#define CHG_PORT 0x004
#if 0
char const *stun_nattype(stun_handle_t *sh)
{
switch(sh->sh_nattype) {
case STUN_NAT_UNKNOWN: return stun_nat_unknown;
case STUN_OPEN_INTERNET: return stun_open_internet;
case STUN_UDP_BLOCKED: return stun_udp_blocked;
case STUN_SYM_UDP_FW: return stun_sym_udp_fw;
case STUN_NAT_FULL_CONE: return stun_nat_full_cone;
case STUN_NAT_SYM: return stun_nat_sym;
case STUN_NAT_RES_CONE: return stun_nat_res_cone;
case STUN_NAT_PORT_RES_CONE: return stun_nat_port_res_cone;
default: return "INVALID NAT TYPE";
}
}
#endif
#define x_insert(l, n, x) \
((l) ? (l)->x##_prev = &(n)->x##_next : 0, \
......@@ -85,69 +106,148 @@ char const stun_nat_unknown[] = "NAT type undetermined",
#define x_is_inserted(n, x) ((n)->x##_prev != NULL)
struct stun_request_s {
stun_request_t *sr_next, **sr_prev;
stun_msg_t *sr_msg;
stun_handle_t *sr_handle;
int sr_root_index;
int sr_state; /**< Progress states */
int sr_retry_count; /**< current retry number */
long sr_timeout; /**< timeout for next sendto() */
stun_request_t *sr_next, **sr_prev; /**< Linked list */
stun_msg_t *sr_msg; /**< STUN message pointer */
stun_handle_t *sr_handle; /**< backpointer, STUN object */
su_localinfo_t sr_localinfo; /**< local addrinfo */
su_sockaddr_t sr_local_addr[1]; /**< local address */
#if 0
int sr_root_index; /**< Index from su_root_register */
#endif
int sr_state; /**< Progress states */
int sr_retry_count; /**< current retry number */
long sr_timeout; /**< timeout for next sendto() */
stun_action_t sr_action; /**< Request type for protocol engine */
int sr_request_mask; /**< Mask consisting of chg_ip and chg_port */
};
struct stun_handle_s
{
su_home_t st_home[1];
su_root_t *st_root; /**< event loop */
int st_root_index; /**< object index of su_root_register() */
su_timer_t *st_connect_timer; /**< timer for TLS connection */
su_home_t sh_home[1];
su_root_t *sh_root; /**< event loop */
int sh_root_index; /**< object index of su_root_register() */
su_timer_t *sh_connect_timer; /**< timer for TLS connection */
stun_request_t *st_requests; /**< outgoing requests list */
stun_request_t *sh_requests; /**< outgoing requests list */
int st_max_retries; /**< max resend for sendto() */
int sh_max_retries; /**< max resend for sendto() */
su_addrinfo_t st_pri_info; /**< server primary info */
su_sockaddr_t st_pri_addr[1]; /**< server primary address */
su_addrinfo_t sh_pri_info; /**< server primary info */
su_sockaddr_t sh_pri_addr[1]; /**< server primary address */
su_addrinfo_t st_sec_info; /**< server secondary info */
su_sockaddr_t st_sec_addr[1]; /**< server secondary address */
su_addrinfo_t sh_sec_info; /**< server secondary info */
su_sockaddr_t sh_sec_addr[1]; /**< server secondary address */
su_localinfo_t st_localinfo; /**< local address returned by server */
su_sockaddr_t st_local_addr[1]; /**< server secondary address */
su_localinfo_t sh_localinfo; /**< local addrinfo */
su_sockaddr_t sh_local_addr[1]; /**< local address */
su_socket_t st_tls_socket; /**< outbound socket */
su_socket_t sh_tls_socket; /**< outbound socket */
#if 0
stun_msg_t *st_binding_request; /**< binding request for server */
stun_msg_t *sh_binding_request; /**< binding request for server */
#endif
SSL_CTX *st_ctx; /**< SSL context for TLS */
SSL *st_ssl; /**< SSL handle for TLS */
stun_msg_t st_tls_request;
stun_msg_t st_tls_response;
int st_nattype; /**< NAT-type, see stun_common.h */
SSL_CTX *sh_ctx; /**< SSL context for TLS */
SSL *sh_ssl; /**< SSL handle for TLS */
stun_msg_t sh_tls_request;
stun_msg_t sh_tls_response;
int sh_nattype; /**< NAT-type, see stun_common.h */
stun_event_f st_callback; /**< callback for calling application */
stun_magic_t *st_context; /**< application context */
stun_event_f sh_callback; /**< callback for calling application */
stun_magic_t *sh_context; /**< application context */
stun_buffer_t st_username;
stun_buffer_t st_passwd;
stun_buffer_t sh_username;
stun_buffer_t sh_passwd;
int st_use_msgint; /**< use message integrity? */
int sh_use_msgint; /**< use message integrity? */
int st_state; /**< Progress states */
int sh_state; /**< Progress states */
int st_bind_socket;
int sh_bind_socket;
int ss_root_index; /**< object index of su_root_register() */
};
#define STUN_STATE_STR(x) case x: return #x
char const *stun_str_state(stun_states_t state)
{
switch (state) {
STUN_STATE_STR(stun_no_assigned_event);
STUN_STATE_STR(stun_tls_connecting);
STUN_STATE_STR(stun_tls_writing);
STUN_STATE_STR(stun_tls_closing);
STUN_STATE_STR(stun_tls_reading);
STUN_STATE_STR(stun_tls_done);
STUN_STATE_STR(stun_bind_init);
STUN_STATE_STR(stun_bind_started);
STUN_STATE_STR(stun_bind_sending);
STUN_STATE_STR(stun_bind_sent);
STUN_STATE_STR(stun_bind_receiving);
STUN_STATE_STR(stun_bind_processing);
STUN_STATE_STR(stun_bind_done);
STUN_STATE_STR(stun_tls_connection_timeout);
STUN_STATE_STR(stun_tls_connection_failed);
STUN_STATE_STR(stun_tls_ssl_connect_failed);
STUN_STATE_STR(stun_request_not_found);
STUN_STATE_STR(stun_bind_error);
STUN_STATE_STR(stun_bind_timeout);
case stun_error:
default: return "stun_error";
}
}
/* NAT TYPES */
typedef enum stun_nattype_t {
stun_nat_unknown,
stun_open_internet,
stun_udp_blocked,
stun_sym_udp_fw,
stun_nat_full_cone,
stun_nat_sym,
stun_nat_res_cone,
stun_nat_port_res_cone,
} stun_nattype_e;
char const *stun_nattype_str[] = {
"NAT type undetermined",
"Open Internet",
"UDP traffic is blocked or server unreachable",
"Symmetric UDP Firewall",
"Full-Cone NAT",
"Symmetric NAT",
"Restricted Cone NAT",
"Port Restricted Cone NAT",
};
char const *stun_nattype(stun_handle_t *sh)
{
return stun_nattype_str[sh->sh_nattype];
}
char const stun_version[] =
"sofia-sip-stun using " OPENSSL_VERSION_TEXT;
static
int process_binding_request(stun_request_t *req, stun_msg_t *binding_response);
static
int process_get_nattype(stun_request_t *req, stun_msg_t *binding_response);
static
int process_get_lifetime(stun_request_t *req, stun_msg_t *binding_response);
static
stun_request_t *stun_create_request(stun_handle_t *sh, stun_action_t action);
static
int stun_send_binding_request(stun_request_t *req,
su_sockaddr_t *srvr_addr);
......@@ -156,12 +256,12 @@ int stun_bind_callback(stun_magic_t *m, su_wait_t *w, stun_handle_t *self);
static
void stun_sendto_timer_cb(su_root_magic_t *magic,
su_timer_t *t,
stun_request_t *req);
su_timer_arg_t *arg);
static
void stun_tls_connect_timer_cb(su_root_magic_t *magic,
su_timer_t *t,
stun_handle_t *se);
su_timer_t *t,
su_timer_arg_t *arg);
......@@ -169,37 +269,10 @@ void stun_tls_connect_timer_cb(su_root_magic_t *magic,
/**
* Return the socket associated with the stun_socket_t structure
*/
int stun_handle_get_bind_socket(stun_handle_t *se)
{
assert(se);
return se->st_bind_socket;
}
char const *stun_str_state(stun_states_t state)
int stun_handle_get_bind_socket(stun_handle_t *sh)
{
switch (state) {
case stun_tls_connecting: return "stun_tls_connecting";
case stun_tls_writing: return "stun_tls_writing";
case stun_tls_closing: return "stun_tls_closing";
case stun_tls_reading: return "stun_tls_reading";
case stun_tls_done: return "stun_tls_done";
case stun_bind_init: return "stun_bind_init";
case stun_bind_started: return "stun_bind_started";
case stun_bind_sending: return "stun_bind_sending";
case stun_bind_sent: return "stun_bind_sent";
case stun_bind_receiving: return "stun_bind_receiving";
case stun_bind_processing: return "stun_bind_processing";
case stun_bind_done: return "stun_bind_done";
case stun_tls_connection_timeout: return "stun_tls_connection_timeout";
case stun_tls_connection_failed: return "stun_tls_connection_failed";
case stun_tls_ssl_connect_failed: return "stun_tls_ssl_connect_failed";
case stun_bind_error: return "stun_bind_error";
case stun_bind_timeout: return "stun_bind_timeout";
case stun_error:
default: return "stun_error";
}
assert(sh);
return sh->sh_bind_socket;
}
......@@ -211,7 +284,7 @@ char const *stun_str_state(stun_states_t state)
*/
su_root_t *stun_handle_root(stun_handle_t *self)
{
return self ? self->st_root : NULL;
return self ? self->sh_root : NULL;
}
......@@ -305,36 +378,35 @@ stun_handle_t *stun_handle_tcreate(stun_magic_t *context,
if (!server)
return NULL;
err = stun_atoaddr(AF_INET, &stun->st_pri_info, stun->st_pri_addr, server);
err = stun_atoaddr(AF_INET, &stun->sh_pri_info, stun->sh_pri_addr, server);
if (err < 0)
return NULL;
stun->st_pri_info.ai_addrlen = 16;
stun->st_pri_info.ai_addr = &stun->st_pri_addr->su_sa;
stun->sh_pri_info.ai_addrlen = 16;
stun->sh_pri_info.ai_addr = &stun->sh_pri_addr->su_sa;
stun->st_sec_info.ai_addrlen = 16;
stun->st_sec_info.ai_addr = &stun->st_sec_addr->su_sa;
stun->sh_sec_info.ai_addrlen = 16;
stun->sh_sec_info.ai_addr = &stun->sh_sec_addr->su_sa;
/* STUN bind related */
stun->st_localinfo.li_addrlen = sizeof(su_sockaddr_t);
stun->st_localinfo.li_addr = stun->st_local_addr;
stun->sh_localinfo.li_addrlen = 16;
stun->sh_localinfo.li_addr = stun->sh_local_addr;
stun->st_nattype = STUN_NAT_UNKNOWN;
stun->sh_nattype = stun_nat_unknown;
stun->st_root = root;
stun->st_context = context;
stun->st_callback = cb;
stun->st_use_msgint = msg_integrity;
stun->sh_root = root;
stun->sh_context = context;
stun->sh_callback = cb;
stun->sh_use_msgint = msg_integrity;
stun->st_max_retries = STUN_MAX_RETRX;
stun->sh_max_retries = STUN_MAX_RETRX;
/* initialize username and password */
stun_init_buffer(&stun->st_username);
stun_init_buffer(&stun->st_passwd);
stun_init_buffer(&stun->sh_username);
stun_init_buffer(&stun->sh_passwd);
stun->st_nattype = STUN_NAT_UNKNOWN;
stun->sh_nattype = stun_nat_unknown;
/* initialize random number generator */
srand(time(NULL));
......@@ -345,7 +417,28 @@ stun_handle_t *stun_handle_tcreate(stun_magic_t *context,
}
stun_request_t *stun_create_request(stun_handle_t *sh)
stun_request_t *stun_action_create_binding_req(stun_handle_t *sh)
{
return stun_create_request(sh, stun_action_binding_request);
}
stun_request_t *stun_action_create_nattype_discovery(stun_handle_t *sh)
{
return stun_create_request(sh, stun_action_get_nattype);
}
stun_request_t *stun_action_create_timeout_discovery(stun_handle_t *sh)
{
return stun_create_request(sh, stun_action_get_lifetime);
}
stun_request_t *stun_action_create_keepalive(stun_handle_t *sh)
{
return stun_create_request(sh, stun_action_keepalive);
}
stun_request_t *stun_create_request(stun_handle_t *sh, stun_action_t action)
{
stun_request_t *req = NULL;
......@@ -353,9 +446,15 @@ stun_request_t *stun_create_request(stun_handle_t *sh)
if (req) {
req->sr_handle = sh;
/* STUN bind related */
req->sr_localinfo.li_addrlen = sizeof(su_sockaddr_t);
req->sr_localinfo.li_addr = req->sr_local_addr;
/* default timeout for next sendto() */
req->sr_timeout = STUN_SENDTO_TIMEOUT;
req->sr_retry_count = 0;
req->sr_action = action;
req->sr_request_mask = 0;
req->sr_msg = calloc(sizeof(stun_msg_t), 1);
}
......@@ -363,17 +462,29 @@ stun_request_t *stun_create_request(stun_handle_t *sh)
return req;
}
void stun_destroy_request(stun_request_t *req)
{
assert(req);
req->sr_handle = NULL;
free(req->sr_msg);
free(req);
return;
}
/** Destroy a STUN client */
void stun_handle_destroy(stun_handle_t *self)
{
if (self->st_bind_socket > 0)
su_close(self->st_bind_socket);
if (self->sh_bind_socket > 0)
su_close(self->sh_bind_socket);
if (self->st_tls_socket > 0)
su_close(self->st_tls_socket);
if (self->sh_tls_socket > 0)
su_close(self->sh_tls_socket);
su_home_zap(self->st_home);
su_home_zap(self->sh_home);
}
......@@ -404,7 +515,7 @@ void stun_handle_destroy(stun_handle_t *self)
* the socket.
*
*/
int stun_handle_bind(stun_handle_t *se,
int stun_handle_bind(stun_handle_t *sh,
int *lifetime,
tag_type_t tag, tag_value_t value,
...)
......@@ -415,7 +526,7 @@ int stun_handle_bind(stun_handle_t *se,
su_sockaddr_t bind_addr;
socklen_t bind_len;
char ipaddr[SU_ADDRSIZE + 2] = { 0 };
stun_request_t *request = NULL;
stun_request_t *req = NULL;
int index;
int events = -1;
su_localinfo_t hints[1] = {{ LI_CANONNAME | LI_NUMERIC }}, *li, *res = NULL;
......@@ -423,13 +534,15 @@ int stun_handle_bind(stun_handle_t *se,
unsigned int port;
ta_list ta;
su_wait_t wait[1] = { SU_WAIT_INIT };
int action = stun_action_no_action;
assert(se);
assert(sh);
ta_start(ta, tag, value);
tl_gets(ta_args(ta),
STUNTAG_SOCKET_REF(s),
STUNTAG_ACTION_REF(action),
TAG_END());
if (s < 0) {
......@@ -437,11 +550,27 @@ int stun_handle_bind(stun_handle_t *se,
return -1;
}
clientinfo = &se->st_localinfo;
if (action != stun_action_no_action)
req = stun_create_request(sh, action);
else
req = stun_action_create_binding_req(sh);
/* Insert this request to the request queue */
if (sh->sh_requests)
x_insert(sh->sh_requests, req, sr);
else
sh->sh_requests = req;
clientinfo = &req->sr_localinfo;
if (action != stun_action_no_action)
goto skip_init;
#if 0
/* Close the previous associated socket */
if (se->st_bind_socket > 0)
su_close(se->st_bind_socket);
if (sh->sh_bind_socket > 0)
su_close(sh->sh_bind_socket);
#endif
/* set socket asynchronous */
if (su_setblocking(s, 0) < 0) {
......@@ -450,7 +579,7 @@ int stun_handle_bind(stun_handle_t *se,
su_close(s);
return -1;
}
se->st_bind_socket = s;
sh->sh_bind_socket = s;
hints->li_family = AF_INET;
if((error = su_getlocalinfo(hints, &res)) == 0) {
......@@ -485,7 +614,7 @@ int stun_handle_bind(stun_handle_t *se,
if (res)
su_freelocalinfo(res);
s = se->st_bind_socket;
s = sh->sh_bind_socket;
events = SU_WAIT_IN | SU_WAIT_ERR;
......@@ -495,9 +624,9 @@ int stun_handle_bind(stun_handle_t *se,
}
/* Register receiving function with events specified above */
if ((index = su_root_register(se->st_root,
if ((index = su_root_register(sh->sh_root,
wait, stun_bind_callback,
se, 0)) < 0) {
sh, 0)) < 0) {
STUN_ERROR(errno, su_root_register);
return -1;
}
......@@ -522,24 +651,16 @@ int stun_handle_bind(stun_handle_t *se,
SU_DEBUG_3(("%s: Local socket bound to: %s:%u\n", __func__, ipaddr,
(unsigned) ntohs(bind_addr.su_port)));
request = stun_create_request(se);
request->sr_root_index = index;
skip_init:
/* Create default message (last two params zeros) */
if (stun_make_binding_req(se, request->sr_msg, 0, 0) < 0)
if (stun_make_binding_req(sh, req, req->sr_msg, 0, 0) < 0)
return -1;
/* Insert this request to the request queue */
if (se->st_requests)
x_insert(se->st_requests, request, sr);
else
se->st_requests = request;
retval = stun_send_binding_request(request, se->st_pri_addr);
retval = stun_send_binding_request(req, sh->sh_pri_addr);
if (retval < 0) {
stun_free_message(request->sr_msg);
stun_free_message(req->sr_msg);
}
if (lifetime) {
if (retval == 0)
......@@ -561,9 +682,9 @@ int stun_handle_bind(stun_handle_t *se,
* This function returns the local address seen from outside.
* Note that the address is not valid until the event stun_clien_done is launched.
*/
su_localinfo_t *stun_handle_get_local_addr(stun_handle_t *se)
su_localinfo_t *stun_request_get_localinfo(stun_request_t *req)
{
return &se->st_localinfo;
return &req->sr_localinfo;
}
......@@ -572,9 +693,9 @@ su_localinfo_t *stun_handle_get_local_addr(stun_handle_t *se)
/** Return type of NAT
* This function may take a long time to finish.
* XXX - mela: not for long!!!
* NAT type is set in ss->se_handle.st_nattype
* nat type is set in ss->se_handle.sh_nattype
*/
int stun_handle_get_nattype(stun_handle_t *se,
int stun_handle_get_nattype(stun_handle_t *sh,
int *addrlen)
{
int retval, lifetime, sockfd;
......@@ -582,17 +703,17 @@ int stun_handle_get_nattype(stun_handle_t *se,
su_sockaddr_t local, /* mapped_addr1, */ mapped_addr2;
su_localinfo_t *mapped_addr1;
sockfd = se->st_bind_socket;
sockfd = sh->sh_bind_socket;
assert(se);
assert(sh);
if ((se->st_state != stun_bind_done) &&
(se->st_state != stun_bind_timeout) &&
(se->st_state != stun_bind_error))
if ((sh->sh_state != stun_bind_done) &&
(sh->sh_state != stun_bind_timeout) &&
(sh->sh_state != stun_bind_error))
return -1;
mapped_addr1 = stun_handle_get_local_addr(se);
mapped_addr1 = stun_handle_get_local_addr(sh);
#if 0
len = sizeof(mapped_addr1);
......@@ -601,13 +722,13 @@ int stun_handle_get_nattype(stun_handle_t *se,
/* retval = stun_bind(ss, &mapped_addr1, &lifetime); */
#endif
if (se->st_state == stun_bind_timeout) {
se->st_nattype = STUN_UDP_BLOCKED;
if (sh->sh_state == stun_bind_timeout) {
sh->sh_nattype = stun_udp_blocked;
/* otherwise unknown nat type */
return 0;
}
else if (se->st_state == stun_bind_error) {
se->st_nattype = STUN_NAT_UNKNOWN;
else if (sh->sh_state == stun_bind_error) {
sh->sh_nattype = stun_nat_unknown;
return 0;
}
else {
......@@ -619,94 +740,118 @@ int stun_handle_get_nattype(stun_handle_t *se,
if (memcmp(&local, &mapped_addr1->li_addr, 8) == 0) {
/* conduct TEST II */
memset(&mapped_addr2, 0, sizeof(mapped_addr2));
retval = stun_send_binding_request(se, se->st_pri_addr, 1, 1);
retval = stun_send_binding_request(sh, sh->sh_pri_addr, 1, 1);
if (retval == -1) {
if (errno == ETIMEDOUT) {
/* No Response: Type 3 - Sym UDP FW */
retval = 0;
se->st_nattype = STUN_SYM_UDP_FW;
sh->sh_nattype = stun_sym_udp_fw;
} /* otherwise unknown nat type */
}
else {
/* Response: Type 1 - Open Internet */
se->st_nattype = STUN_OPEN_INTERNET;
sh->sh_nattype = stun_open_internet;
}
}
/* Different IP */
else {
memset(&mapped_addr2, 0, sizeof(mapped_addr2));
retval = stun_send_binding_request(se, se->st_pri_addr, 1, 1);
retval = stun_send_binding_request(sh, sh->sh_pri_addr, 1, 1);
if (retval == -1) {
if (errno == ETIMEDOUT) {
/* No Response */
retval = stun_send_binding_request(se, se->st_sec_addr, 0, 0);
retval = stun_send_binding_request(sh, sh->sh_sec_addr, 0, 0);
/* response comes back, has to be the case */
if (retval == 0) {
if (memcmp(&mapped_addr1, &mapped_addr2, 8) == 0) {
/* Same Public IP and port, Test III, server ip 0 or 1 should be
same */
retval = stun_send_binding_request(se, se->st_pri_addr, 0, 1);
retval = stun_send_binding_request(sh, sh->sh_pri_addr, 0, 1);
if(retval==0) {
/* Response: Type 6 - Restricted */
se->st_nattype = STUN_NAT_RES_CONE;
sh->sh_nattype = stun_nat_res_cone;
}
else if(errno==ETIMEDOUT) {
/* No response: Type 7 - Port Restricted */
retval = 0;
se->st_nattype = STUN_NAT_PORT_RES_CONE;
sh->sh_nattype = stun_nat_port_res_cone;
}
}
else {
/* Different Public IP: Type 5 - Sym NAT */
se->st_nattype = STUN_NAT_SYM;
sh->sh_nattype = stun_nat_sym;
}
} /* otherwise there is a sudden network problem */
} /* otherwise unknown nat type */
}
else {
/* Response: Type 4 - Full Cone */
se->st_nattype = STUN_NAT_FULL_CONE;
sh->sh_nattype = stun_nat_full_cone;
}
}
}
return retval;
}
#endif /* if 0 */
int stun_handle_get_nattype(stun_handle_t *se,
su_localinfo_t *my_addr,
int *addrlen)
int stun_handle_get_nattype(stun_handle_t *sh,
#if 0
su_localinfo_t *my_addr,
int *addrlen,
#endif
tag_type_t tag, tag_value_t value,
...)
{
int nattype = STUN_NAT_UNKNOWN;
int nattype = stun_nat_unknown;
int retval, lifetime, sockfd;
socklen_t locallen, len;
/* socklen_t locallen, len; */
#if 0
struct sockaddr_in local, /* mapped_addr1, */ mapped_addr2;
su_localinfo_t mapped_addr1;
#endif
ta_list ta;
sockfd = se->st_bind_socket;
ta_start(ta, tag, value);
sockfd = sh->sh_bind_socket;
#if 0
assert(my_addr && my_addr->li_addrlen != 0);
len = sizeof(mapped_addr1);
memcpy(&mapped_addr1, my_addr, len);
/* mapped_addr1.li_addr.su_port = 0; */ /* wild card for get_nattype */
#endif
/* retval = stun_bind(ss, &mapped_addr1, &lifetime); */
retval = stun_handle_bind(se, &lifetime);
/* This launches the binding process, but with a different state
* machine than the default one: get_nattype is the specified action
* here */
retval = stun_handle_bind(sh, &lifetime,
STUNTAG_ACTION(stun_action_get_nattype),
TAG_NEXT(ta_args(ta)));
if (retval == -1) {
if (errno == ETIMEDOUT) {
/* No Response: Type 2 - UDP Blocked */
retval = 0; /* time out is a legitimate response */
nattype = STUN_UDP_BLOCKED;
nattype = stun_udp_blocked;
} /* otherwise unknown nat type */
}
ta_end(ta);
return 0;
}
#if 0