Commit 4429a8c3 authored by Martti Mela's avatar Martti Mela

stun api upd's also for tls; tport

darcs-hash:20060327141906-1b897-70e954667ca50a9bfbef2920cf37cd09f0e85bee.gz
parent 2ff3a96b
......@@ -159,10 +159,9 @@ typedef void (*stun_dns_lookup_f)(stun_dns_lookup_t *self,
/* -------------------------------------------------------------------
* Functions for managing STUN handles. */
stun_handle_t *stun_handle_create(stun_magic_t *context,
su_root_t *root,
stun_event_f cb,
tag_type_t tag, tag_value_t value, ...);
stun_handle_t *stun_handle_init(su_root_t *root,
tag_type_t tag, tag_value_t value, ...);
int stun_handle_release(stun_handle_t *sh, su_socket_t s);
void stun_handle_destroy(stun_handle_t *sh);
......@@ -180,6 +179,12 @@ int stun_process_request(su_socket_t s, stun_msg_t *req,
/* -------------------------------------------------------------------
* Functions for 'Binding Discovery' usage (RFC3489/3489bis) */
int stun_discovery_release_socket(stun_discovery_t *sd);
int stun_obtain_shared_secret(stun_handle_t *sh, stun_discovery_f,
stun_discovery_magic_t *magic,
tag_type_t tag, tag_value_t value, ...);
int stun_request_shared_secret(stun_handle_t *sh);
int stun_bind(stun_handle_t *sh,
......@@ -242,6 +247,11 @@ void stun_dns_lookup_destroy(stun_dns_lookup_t *self);
* Deprecated functions. These are supported with limited
* compatibility. */
stun_handle_t *stun_handle_create(stun_magic_t *context,
su_root_t *root,
stun_event_f cb,
tag_type_t tag, tag_value_t value, ...);
su_root_t *stun_handle_root(stun_handle_t *sh);
int stun_handle_request_shared_secret(stun_handle_t *sh);
......
......@@ -71,10 +71,10 @@ extern tag_typedef_t stuntag_socket;
#define STUNTAG_SOCKET_REF(x) stuntag_socket_ref, tag_int_vr(&(x))
extern tag_typedef_t stuntag_socket_ref;
#define STUNTAG_REGISTER_SOCKET(x) stuntag_register_socket, tag_int_v(x)
extern tag_typedef_t stuntag_register_socket;
#define STUNTAG_REGISTER_SOCKET_REF(x) stuntag_register_socket_ref, tag_int_vr(&(x))
extern tag_typedef_t stuntag_register_socket_ref;
#define STUNTAG_REGISTER_EVENTS(x) stuntag_register_events, tag_int_v(x)
extern tag_typedef_t stuntag_register_events;
#define STUNTAG_REGISTER_EVENTS_REF(x) stuntag_register_events_ref, tag_int_vr(&(x))
extern tag_typedef_t stuntag_register_events_ref;
#define STUNTAG_ACTION(x) stuntag_action, tag_int_v(x)
extern tag_typedef_t stuntag_action;
......
......@@ -380,6 +380,106 @@ int stun_is_requested(tag_type_t tag, tag_value_t value, ...)
return stun_server != NULL;
}
/**
* Creates a STUN handle.
*
* The created handles can be used for STUN binding discovery,
* keepalives, and other STUN usages.
*
* @param root eventloop to used by the stun state machine
* @param tag,value,... tag-value list
*
* @TAGS
* @TAG STUNTAG_DOMAIN() domain to use in DNS-SRV based STUN server
* @TAG STUNTAG_SERVER() stun server hostname or dotted IPv4 address
* @TAG STUNTAG_REQUIRE_INTEGRITY() true if msg integrity should be
* used enforced
*
*/
stun_handle_t *stun_handle_init(su_root_t *root,
tag_type_t tag, tag_value_t value, ...)
{
stun_handle_t *stun = NULL;
char const *server = NULL, *domain = NULL;
int req_msg_integrity = 1;
int err;
ta_list ta;
enter;
ta_start(ta, tag, value);
tl_gets(ta_args(ta),
STUNTAG_SERVER_REF(server),
STUNTAG_DOMAIN_REF(domain),
STUNTAG_REQUIRE_INTEGRITY_REF(req_msg_integrity),
TAG_END());
stun = su_home_clone(NULL, sizeof(*stun));
if (!stun) {
SU_DEBUG_3(("%s: %s failed\n", __func__, "su_home_clone()"));
return NULL;
}
/* Enviroment overrides */
if (getenv("STUN_SERVER")) {
server = getenv("STUN_SERVER");
SU_DEBUG_5(("%s: using STUN_SERVER=%s\n", __func__, server));
}
SU_DEBUG_5(("%s(\"%s\"): called\n",
__func__, server));
/* fail, if no server or a domain for a DNS-SRV lookup is specified */
if (!server && !domain)
return NULL;
stun->sh_pri_info.ai_addrlen = 16;
stun->sh_pri_info.ai_addr = &stun->sh_pri_addr->su_sa;
stun->sh_sec_info.ai_addrlen = 16;
stun->sh_sec_info.ai_addr = &stun->sh_sec_addr->su_sa;
stun->sh_localinfo.li_addrlen = 16;
stun->sh_localinfo.li_addr = stun->sh_local_addr;
stun->sh_domain = su_strdup(stun->sh_home, domain);
stun->sh_dns_lookup = NULL;
if (server) {
err = stun_atoaddr(AF_INET, &stun->sh_pri_info, server);
if (err < 0)
return NULL;
}
stun->sh_nattype = stun_nat_unknown;
stun->sh_root = root;
/* always try TLS: */
stun->sh_use_msgint = 1;
/* whether use of shared-secret msgint is required */
stun->sh_req_msgint = req_msg_integrity;
stun->sh_max_retries = STUN_MAX_RETRX;
/* initialize username and password */
stun_init_buffer(&stun->sh_username);
stun_init_buffer(&stun->sh_passwd);
stun->sh_nattype = stun_nat_unknown;
/* initialize random number generator */
srand(time(NULL));
ta_end(ta);
return stun;
}
/**
* Creates a STUN handle.
*
......@@ -398,6 +498,8 @@ int stun_is_requested(tag_type_t tag, tag_value_t value, ...)
* used enforced
*
*/
/* Deprecated. Use stun_agent_create() */
stun_handle_t *stun_handle_create(stun_magic_t *context,
su_root_t *root,
stun_event_f cb,
......@@ -488,7 +590,7 @@ stun_handle_t *stun_handle_create(stun_magic_t *context,
/* Deprecated. Use stun_request_shared_secret() */
int stun_handle_request_shared_secret(stun_handle_t *sh)
{
return stun_request_shared_secret(sh);
return stun_obtain_shared_secret(sh, NULL, NULL, TAG_NULL());
}
/**
......@@ -496,7 +598,10 @@ int stun_handle_request_shared_secret(stun_handle_t *sh)
* Result will be trigged in STUN handle callback (state
* one of stun_tls_*).
**/
int stun_request_shared_secret(stun_handle_t *sh)
int stun_obtain_shared_secret(stun_handle_t *sh,
stun_discovery_f sdf,
stun_discovery_magic_t *magic,
tag_type_t tag, tag_value_t value, ...)
{
#if defined(HAVE_OPENSSL)
int events = -1;
......@@ -563,7 +668,7 @@ int stun_request_shared_secret(stun_handle_t *sh)
SU_DEBUG_9(("%s: %s: %s\n", __func__, "connect",
su_strerror(err)));
sd = stun_discovery_create(sh, stun_action_tls_query, NULL, NULL);
sd = stun_discovery_create(sh, stun_action_tls_query, sdf, magic);
sd->sd_socket = s;
/* req = stun_request_create(sd); */
......@@ -1020,7 +1125,7 @@ int stun_bind(stun_handle_t *sh,
tl_gets(ta_args(ta),
STUNTAG_SOCKET_REF(s),
STUNTAG_REGISTER_SOCKET_REF(s_reg),
STUNTAG_REGISTER_EVENTS_REF(s_reg),
TAG_END());
ta_end(ta);
......@@ -1175,7 +1280,7 @@ int stun_get_nattype(stun_handle_t *sh,
tl_gets(ta_args(ta),
STUNTAG_SOCKET_REF(s),
STUNTAG_REGISTER_SOCKET_REF(s_reg),
STUNTAG_REGISTER_EVENTS_REF(s_reg),
STUNTAG_SERVER_REF(server),
TAG_END());
......@@ -1291,8 +1396,12 @@ static int stun_tls_callback(su_root_magic_t *m, su_wait_t *w, su_wakeup_arg_t *
"Proceed without username/password.\n", __func__));
sd->sd_state = stun_tls_connection_failed;
self->sh_callback(self->sh_context, self, NULL, sd,
sd->sd_action, sd->sd_state);
if (sd->sd_callback)
sd->sd_callback(sd->sd_magic, self, NULL, sd, sd->sd_action, sd->sd_state);
else
self->sh_callback(self->sh_context, self, NULL, sd,
sd->sd_action, sd->sd_state);
return 0;
}
......@@ -1362,8 +1471,13 @@ static int stun_tls_callback(su_root_magic_t *m, su_wait_t *w, su_wakeup_arg_t *
stun_free_buffer(&msg_req->enc_buf);
sd->sd_state = stun_tls_connection_failed;
self->sh_callback(self->sh_context, self, NULL, sd,
sd->sd_action, sd->sd_state);
if (sd->sd_callback)
sd->sd_callback(sd->sd_magic, self, NULL, sd, sd->sd_action, sd->sd_state);
else
self->sh_callback(self->sh_context, self, NULL, sd,
sd->sd_action, sd->sd_state);
return -1;
}
......@@ -1486,8 +1600,12 @@ static int stun_tls_callback(su_root_magic_t *m, su_wait_t *w, su_wakeup_arg_t *
self->sh_use_msgint = 1;
sd->sd_state = stun_tls_done;
self->sh_callback(self->sh_context, self, NULL, sd,
sd->sd_action, sd->sd_state);
if (sd->sd_callback)
sd->sd_callback(sd->sd_magic, self, NULL, sd, sd->sd_action, sd->sd_state);
else
self->sh_callback(self->sh_context, self, NULL, sd,
sd->sd_action, sd->sd_state);
break;
......@@ -1599,11 +1717,11 @@ stun_action_t get_action(stun_request_t *req)
/* Find request from the request queue, based on TID */
static inline
stun_request_t *find_request(stun_handle_t *self, uint16_t *id)
stun_request_t *find_request(stun_handle_t *self, void *id)
{
uint16_t *match;
void *match;
stun_request_t *req = NULL;
int len = sizeof(uint16_t)*8;
int len = sizeof (uint8_t) * 16; /* sizeof tran_id */
for (req = self->sh_requests; req; req = req->sr_next) {
match = req->sr_msg->stun_hdr.tran_id;
......@@ -1695,7 +1813,7 @@ static int do_action(stun_handle_t *sh, stun_msg_t *msg)
{
stun_request_t *req = NULL;
stun_action_t action = stun_action_no_action;
uint16_t *id;
void *id;
enter;
......@@ -2568,7 +2686,7 @@ int stun_handle_get_lifetime(stun_handle_t *sh,
*
* @TAGS
* @TAG STUNTAG_SOCKET Bind socket for STUN
* @TAG STUNTAG_REGISTER_SOCKET Register socket for eventloop owned by STUN
* @TAG STUNTAG_REGISTER_EVENTS Register socket for eventloop owned by STUN
* @TAG STUNTAG_SERVER() stun server hostname or dotted IPv4 address
*
* @return 0 on success, non-zero on error
......@@ -2598,7 +2716,7 @@ int stun_get_lifetime(stun_handle_t *sh,
tl_gets(ta_args(ta),
STUNTAG_SOCKET_REF(s),
STUNTAG_REGISTER_SOCKET_REF(s_reg),
STUNTAG_REGISTER_EVENTS_REF(s_reg),
STUNTAG_SERVER_REF(server),
TAG_END());
......@@ -2786,6 +2904,21 @@ int stun_process_message(stun_handle_t *sh, su_socket_t s,
}
int stun_discovery_release_socket(stun_discovery_t *sd)
{
stun_handle_t *sh = sd->sd_handle;
if (su_root_deregister(sh->sh_root, sd->sd_index) >= 0) {
SU_DEBUG_3(("%s: socket deregistered from STUN \n", __func__));
sd->sd_index = -1; /* mark index as deregistered */
return 0;
}
return -1;
}
/**
* Unregisters socket from STUN handle event loop
*/
......
......@@ -105,6 +105,7 @@ int stun_parse_message(stun_msg_t *msg)
}
#if 1
int stun_parse_attribute(stun_msg_t *msg, unsigned char *p) {
int len;
......@@ -189,12 +190,15 @@ int stun_parse_attribute(stun_msg_t *msg, unsigned char *p) {
return len+4;
}
#else
int stun_parse_attribute(stun_msg_t *msg, unsigned char *p) {
attr = (stun_attr_t *)calloc(1, sizeof(stun_attr_t));
if (!attr)
return -1;
return stun_parse_attr_any(attr, type, len, p);
}
#endif
int stun_parse_attr_address(stun_attr_t *attr,
const unsigned char *p,
......@@ -550,7 +554,6 @@ int stun_init_message(stun_msg_t *msg) {
int stun_free_message(stun_msg_t *msg) {
int i;
stun_attr_t *p, *p2;
/* clearing header */
......@@ -618,9 +621,8 @@ int stun_send_message(su_socket_t s, su_sockaddr_t *to_addr,
*/
int stun_encode_message(stun_msg_t *msg, stun_buffer_t *pwd) {
int i, z, len, buf_len = 0;
int z, len, buf_len = 0;
unsigned char *buf;
uint16_t tmp16;
stun_attr_t *attr, *msg_int=NULL;
if(msg->enc_buf.data == NULL) {
......
......@@ -128,24 +128,25 @@ tag_typedef_t stuntag_integrity = BOOLTAG_TYPEDEF(integrity);
*/
tag_typedef_t stuntag_socket = INTTAG_TYPEDEF(socket);
/**@def STUNTAG_REGISTER_SOCKET(x)
/**@def STUNTAG_REGISTER_EVENTS(x)
*
* Register socket for eventloop owned by STUN.
* Register socket events for eventloop owned by STUN.
*
* @par Used with
* stun_handle_bind() \n
* stun_handle_get_lifetime() \n
* stun_handle_get_nattype() \n
* stun_bind() \n
* stun_get_lifetime() \n
* stun_get_nattype() \n
* stun_keepalive() \n
*
* @par Parameter type
* int (su_register_socket_t)
*
* @par Values
* IPv4 (AF_INET) register_socket
* IPv4 (AF_INET) register_events
*
* Corresponding tag taking reference parameter is STUNTAG_REGISTER_SOCKET_REF()
* Corresponding tag taking reference parameter is STUNTAG_REGISTER_EVENTS_REF()
*/
tag_typedef_t stuntag_register_socket = INTTAG_TYPEDEF(register_socket);
tag_typedef_t stuntag_register_events = INTTAG_TYPEDEF(register_events);
/**@def STUNTAG_ACTION(x)
*
......
......@@ -208,6 +208,7 @@ int tport_keepalive(tport_t *tp, tp_name_t *tpn)
}
#if HAVE_SOFIA_STUN
#if 0
void tport_stun_cb(tport_master_t *mr,
stun_handle_t *sh,
stun_request_t *req,
......@@ -227,6 +228,7 @@ void tport_stun_cb(tport_master_t *mr,
return;
}
#endif
/**Callback for STUN bind
......@@ -307,15 +309,13 @@ tport_nat_initialize_nat_traversal(tport_master_t *mr,
strcasecmp(tpn->tpn_proto, stun_transports[i]) == 0)) {
SU_DEBUG_5(("%s(%p) initializing STUN handle\n", __func__, mr));
nat->stun = stun_handle_create(mr,
mr->mr_root,
tport_stun_cb,
TAG_NEXT(tags));
nat->stun = stun_handle_init(mr->mr_root,
TAG_NEXT(tags));
if (!nat->stun)
return NULL;
if (stun_request_shared_secret(nat->stun) < 0) {
if (stun_obtain_key(nat->stun, tport_stun_tls_cb, mr, TAG_NEXT(tags)) < 0) {
SU_DEBUG_3(("%s: %s failed\n", __func__,
"stun_request_shared_secret()"));
}
......
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