Commit 3fe54d91 authored by Martti Mela's avatar Martti Mela

stunc works, kikkelis kokkelis!!

darcs-hash:20060328083945-1b897-e2a28c843a13b7d7441ab7692ded8e67772fc088.gz
parent 422ca869
......@@ -181,7 +181,9 @@ int stun_bind(stun_handle_t *sh,
stun_discovery_f, stun_discovery_magic_t *magic,
tag_type_t tag, tag_value_t value, ...);
su_sockaddr_t *stun_discovery_get_address(stun_discovery_t *sd);
int stun_discovery_get_address(stun_discovery_t *sd,
void *addr,
socklen_t *return_addrlen);
su_socket_t stun_discovery_get_socket(stun_discovery_t *sd);
int stun_discovery_release_socket(stun_discovery_t *sd);
......
......@@ -630,8 +630,7 @@ int stun_obtain_shared_secret(stun_handle_t *sh,
ai = &sh->sh_pri_info;
if (sh->sh_use_msgint == 1) {
SU_DEBUG_3(("Contacting Server to obtain shared secret. " \
"Please wait.\n"));
SU_DEBUG_3(("%s: Obtaining shared secret.\n", __func__));
}
else {
SU_DEBUG_3(("No message integrity enabled.\n"));
......@@ -1163,12 +1162,27 @@ int stun_bind(stun_handle_t *sh,
* 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_sockaddr_t *stun_discovery_get_address(stun_discovery_t *sd)
int stun_discovery_get_address(stun_discovery_t *sd,
void *addr,
socklen_t *return_addrlen)
{
int siz;
enter;
return sd->sd_addr_seen_outside;
assert(sd && addr);
siz = SU_SOCKADDR_SIZE(sd->sd_addr_seen_outside);
/* Check if enough memory provided */
if (siz > *return_addrlen)
return errno = EFAULT, -1;
else
*return_addrlen = siz;
memcpy(addr, sd->sd_addr_seen_outside, siz);
return 0;
}
static stun_discovery_t *stun_discovery_create(stun_handle_t *sh,
......
......@@ -39,6 +39,7 @@
typedef struct stunc_s stunc_t;
#define SU_ROOT_MAGIC stunc_t
#define STUN_MAGIC_T stunc_t
#define STUN_DISCOVERY_MAGIC_T stunc_t
#include "sofia-sip/stun.h"
#include "sofia-sip/stun_tag.h"
......@@ -53,72 +54,142 @@ typedef struct stunc_s stunc_t;
char const *name = "stunc";
/* Our UDP socket */
su_socket_t s;
void usage(int exitcode)
{
fprintf(stderr, "usage: %s server use_msgint\n", name);
fprintf(stderr, "usage: %s server <use message integrity> <determine NAT type>\n", name);
exit(exitcode);
}
struct stunc_s {
int nothing;
su_socket_t sc_socket;
int sc_test_nattype;
};
void stunc_callback(stunc_t *stunc, stun_handle_t *sh,
stun_request_t *req,
stun_discovery_t *sd,
stun_action_t action,
stun_state_t event)
static
void stunc_nattype_cb(stunc_t *stunc,
stun_handle_t *sh,
stun_request_t *req,
stun_discovery_t *sd,
stun_action_t action,
stun_state_t event);
static
void stunc_bind_cb(stunc_t *stunc,
stun_handle_t *sh,
stun_request_t *req,
stun_discovery_t *sd,
stun_action_t action,
stun_state_t event);
static
void stunc_ss_cb(stunc_t *stunc,
stun_handle_t *sh,
stun_request_t *req,
stun_discovery_t *sd,
stun_action_t action,
stun_state_t event)
{
su_sockaddr_t *sa = NULL;
char ipaddr[48];
char const *nattype;
int lifetime;
int err;
SU_DEBUG_3(("%s: %s\n", __func__, stun_str_state(event)));
switch (event) {
case stun_tls_done:
err = stun_bind(sh, stunc_bind_cb, stunc,
STUNTAG_SOCKET(stunc->sc_socket),
STUNTAG_REGISTER_EVENTS(1),
TAG_NULL());
if (err < 0) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_bind()"));
su_root_break(stun_handle_root(sh));
}
case stun_tls_connection_failed:
case stun_tls_connection_timeout:
SU_DEBUG_0(("%s: TLS query done, start binding process.\n", __func__));
if (stun_handle_bind(sh, STUNTAG_SOCKET(s), TAG_NULL()) < 0) {
SU_DEBUG_0(("%s: Obtaining shared secret failed, starting binding process.\n",
__func__));
err = stun_bind(sh, stunc_bind_cb, stunc,
STUNTAG_SOCKET(stunc->sc_socket),
STUNTAG_REGISTER_EVENTS(1),
TAG_NULL());
if (err < 0) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_bind()"));
su_root_break(stun_handle_root(sh));
}
break;
case stun_discovery_done:
if (action == stun_action_test_nattype) {
nattype = stun_nattype(sd);
SU_DEBUG_0(("%s: NAT type: %s\n", __func__, nattype));
}
else if (action == stun_action_test_lifetime) {
lifetime = stun_lifetime(sd);
SU_DEBUG_0(("%s: Life time is %d s.\n", __func__, lifetime));
case stun_tls_connection_timeout:
SU_DEBUG_0(("%s: Timeout when obtaining shared secret, starting binding process.\n",
__func__));
err = stun_bind(sh, stunc_bind_cb, stunc,
STUNTAG_SOCKET(stunc->sc_socket),
STUNTAG_REGISTER_EVENTS(1),
TAG_NULL());
if (err < 0) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_bind()"));
su_root_break(stun_handle_root(sh));
}
break;
default:
su_root_break(stun_handle_root(sh));
break;
}
return;
}
static
void stunc_bind_cb(stunc_t *stunc,
stun_handle_t *sh,
stun_request_t *req,
stun_discovery_t *sd,
stun_action_t action,
stun_state_t event)
{
su_sockaddr_t sa[1];
char ipaddr[48];
char const *nattype;
int lifetime, err;
socklen_t addrlen;
SU_DEBUG_3(("%s: %s\n", __func__, stun_str_state(event)));
switch (event) {
case stun_bind_done:
sa = stun_discovery_get_address(sd);
addrlen = sizeof(*sa);
memset(sa, 0, addrlen);
if (stun_discovery_get_address(sd, sa, &addrlen) < 0) {
return;
SU_DEBUG_0(("%s: stun_discovery_get_address() failed", __func__));
}
SU_DEBUG_0(("%s: local address NATed as %s:%u\n", __func__,
inet_ntop(sa->su_family, SU_ADDR(sa),
ipaddr, sizeof(ipaddr)),
(unsigned) ntohs(sa->su_port)));
/* su_root_break(stun_handle_root(sh)); */
/* XXX: do not work (2006/03;kv) */
#if 0
if (stun_test_nattype(sh, STUNTAG_SOCKET(s), TAG_NULL()) < 0) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_test_nattype()"));
su_root_break(stun_handle_root(sh));
if (stunc->sc_test_nattype) {
err = stun_test_nattype(sh, stunc_nattype_cb, stunc,
STUNTAG_REGISTER_EVENTS(1),
STUNTAG_SOCKET(stunc->sc_socket),
TAG_NULL());
if (err < 0) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_test_nattype()"));
su_root_break(stun_handle_root(sh));
}
}
else
su_root_break(stun_handle_root(sh));
#if 0
if (stun_handle_test_lifetime(sh, STUNTAG_SOCKET(s), TAG_NULL()) < 0) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_test_lifetime()"));
su_root_break(stun_handle_root(sh));
......@@ -139,6 +210,44 @@ void stunc_callback(stunc_t *stunc, stun_handle_t *sh,
case stun_bind_timeout:
default:
su_root_break(stun_handle_root(sh));
break;
}
return;
}
static
void stunc_nattype_cb(stunc_t *stunc,
stun_handle_t *sh,
stun_request_t *req,
stun_discovery_t *sd,
stun_action_t action,
stun_state_t event)
{
su_sockaddr_t sa[1];
char ipaddr[48];
char const *nattype;
int lifetime;
socklen_t addrlen;
SU_DEBUG_3(("%s: %s\n", __func__, stun_str_state(event)));
switch (event) {
case stun_discovery_timeout:
if (action == stun_action_binding_request) {
su_root_break(stun_handle_root(sh));
}
break;
case stun_discovery_done:
SU_DEBUG_3(("%s: NAT type determined to be %s.\n", __func__, stun_nattype(sd)));
case stun_error:
default:
su_root_break(stun_handle_root(sh));
break;
}
......@@ -148,38 +257,43 @@ void stunc_callback(stunc_t *stunc, stun_handle_t *sh,
int main(int argc, char *argv[])
{
int msg_integrity;
int param_integrity, param_nattype, err;
stunc_t stunc[1];
su_root_t *root = su_root_create(stunc);
stun_handle_t *sh;
if (argc != 3)
/* Our UDP socket */
su_socket_t s;
if (argc != 4)
usage(1);
msg_integrity = atoi(argv[2]);
param_integrity = atoi(argv[2]);
param_nattype = atoi(argv[3]);
/* Running this test requires a local STUN server on default port */
sh = stun_handle_create(stunc,
root,
stunc_callback,
STUNTAG_SERVER(argv[1]),
STUNTAG_REQUIRE_INTEGRITY(msg_integrity),
TAG_NULL());
sh = stun_handle_init(root,
STUNTAG_SERVER(argv[1]),
STUNTAG_REQUIRE_INTEGRITY(param_integrity),
TAG_NULL());
if (!sh) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_tcreate()"));
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_init()"));
return -1;
}
s = su_socket(AF_INET, SOCK_DGRAM, 0);
if (s == -1) {
SU_DEBUG_0(("%s: %s failed: %s\n", __func__, "stun_socket_create()", su_gli_strerror(errno)));
SU_DEBUG_0(("%s: %s failed: %s\n", __func__, "su_socket()", su_gli_strerror(errno)));
return -1;
}
if (msg_integrity == 1) {
if (stun_handle_request_shared_secret(sh) < 0) {
stunc->sc_socket = s;
stunc->sc_test_nattype = param_nattype;
if (param_integrity == 1) {
if (stun_obtain_shared_secret(sh, stunc_ss_cb, stunc, TAG_NULL()) < 0) {
SU_DEBUG_3(("%s: %s failed\n", __func__, "stun_handle_request_shared_secret()"));
return -1;
}
......@@ -189,8 +303,13 @@ int main(int argc, char *argv[])
}
/* If no TSL query, start bind here */
if (stun_handle_bind(sh, STUNTAG_SOCKET(s), TAG_NULL()) < 0) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_handle_bind()"));
err = stun_bind(sh, stunc_bind_cb, stunc,
STUNTAG_SOCKET(s),
STUNTAG_REGISTER_EVENTS(1),
TAG_NULL());
if (err < 0) {
SU_DEBUG_0(("%s: %s failed\n", __func__, "stun_bind()"));
return -1;
}
su_root_run(root);
......
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