Commit 6198b3cd authored by Kai Vehmanen's avatar Kai Vehmanen

Preparation for adding STUN control support.

darcs-hash:20071115164921-77cd4-51a973a5d5ce4fb45e3419418e165d90e70fe0b2.gz
parent 725c27ba
...@@ -101,20 +101,11 @@ stun_bind_alloc (stun_bind_t **restrict context, int fd, ...@@ -101,20 +101,11 @@ stun_bind_alloc (stun_bind_t **restrict context, int fd,
} }
stun_init_request (ctx->trans.msg.buf, STUN_BINDING); stun_init_request (ctx->trans.msg.buf, STUN_BINDING);
ctx->trans.msg.length = sizeof (ctx->trans.msg.buf);
return 0; return 0;
} }
static int
stun_bind_launch (stun_bind_t *ctx)
{
int val = stun_trans_start (&ctx->trans);
if (val)
stun_bind_cancel (ctx);
return val;
}
int stun_bind_start (stun_bind_t **restrict context, int fd, int stun_bind_start (stun_bind_t **restrict context, int fd,
const struct sockaddr *restrict srv, const struct sockaddr *restrict srv,
socklen_t srvlen) socklen_t srvlen)
...@@ -126,16 +117,19 @@ int stun_bind_start (stun_bind_t **restrict context, int fd, ...@@ -126,16 +117,19 @@ int stun_bind_start (stun_bind_t **restrict context, int fd,
return val; return val;
ctx = *context; ctx = *context;
ctx->trans.msg.length = sizeof (ctx->trans.msg.buf);
val = stun_finish (ctx->trans.msg.buf, &ctx->trans.msg.length); val = stun_finish (ctx->trans.msg.buf, &ctx->trans.msg.length);
if (val) if (val)
{ goto error;
stun_bind_cancel (ctx);
return val; val = stun_trans_start (&ctx->trans);
} if (val)
goto error;
return stun_bind_launch (ctx); return 0;
error:
stun_bind_cancel (ctx);
return val;
} }
...@@ -276,10 +270,11 @@ stun_conncheck_start (stun_bind_t **restrict context, int fd, ...@@ -276,10 +270,11 @@ stun_conncheck_start (stun_bind_t **restrict context, int fd,
assert (username != NULL); assert (username != NULL);
assert (password != NULL); assert (password != NULL);
val = stun_bind_alloc (&ctx, fd, srv, srvlen); val = stun_bind_alloc (context, fd, srv, srvlen);
if (val) if (val)
return val; return val;
ctx = *context;
ctx->trans.key.length = strlen (password); ctx->trans.key.length = strlen (password);
ctx->trans.key.value = malloc (ctx->trans.key.length); ctx->trans.key.value = malloc (ctx->trans.key.length);
if (ctx->trans.key.value == NULL) if (ctx->trans.key.value == NULL)
...@@ -288,7 +283,6 @@ stun_conncheck_start (stun_bind_t **restrict context, int fd, ...@@ -288,7 +283,6 @@ stun_conncheck_start (stun_bind_t **restrict context, int fd,
goto error; goto error;
} }
*context = ctx;
memcpy (ctx->trans.key.value, password, ctx->trans.key.length); memcpy (ctx->trans.key.value, password, ctx->trans.key.length);
if (cand_use) if (cand_use)
...@@ -311,17 +305,115 @@ stun_conncheck_start (stun_bind_t **restrict context, int fd, ...@@ -311,17 +305,115 @@ stun_conncheck_start (stun_bind_t **restrict context, int fd,
if (val) if (val)
goto error; goto error;
ctx->trans.msg.length = sizeof (ctx->trans.msg.buf);
val = stun_finish_short (ctx->trans.msg.buf, &ctx->trans.msg.length, val = stun_finish_short (ctx->trans.msg.buf, &ctx->trans.msg.length,
username, password, NULL); username, password, NULL);
if (val) if (val)
goto error; goto error;
return stun_bind_launch (ctx); val = stun_trans_start (&ctx->trans);
if (val)
goto error;
return 0;
error: error:
stun_bind_cancel (*context); stun_bind_cancel (ctx);
return val; return val;
} }
/** STUN NAT control */
struct stun_nested_s
{
stun_bind_t *bind;
struct sockaddr_storage mapped;
uint32_t refresh;
uint32_t bootnonce;
};
int stun_nested_start (stun_nested_t **restrict context, int fd,
const struct sockaddr *restrict mapad,
const struct sockaddr *restrict natad,
socklen_t adlen, uint32_t refresh)
{
stun_nested_t *ctx;
int val;
if (adlen > sizeof (ctx->mapped))
return ENOBUFS;
ctx = malloc (sizeof (*ctx));
memcpy (&ctx->mapped, mapad, adlen);
ctx->refresh = 0;
ctx->bootnonce = 0;
/* TODO: forcily set port to 3478 */
val = stun_bind_alloc (&ctx->bind, fd, natad, adlen);
if (val)
return val;
*context = ctx;
val = stun_append32 (ctx->bind->trans.msg.buf,
sizeof (ctx->bind->trans.msg.buf),
STUN_REFRESH_INTERVAL, refresh);
if (val)
goto error;
val = stun_finish (ctx->bind->trans.msg.buf,
&ctx->bind->trans.msg.length);
if (val)
goto error;
val = stun_trans_start (&ctx->bind->trans);
if (val)
goto error;
return 0;
error:
stun_bind_cancel (ctx->bind);
return val;
}
int stun_nested_process (stun_nested_t *restrict ctx,
const void *restrict buf, size_t len,
struct sockaddr *restrict intad, socklen_t *adlen)
{
struct sockaddr_storage mapped;
socklen_t mappedlen = sizeof (mapped);
int val;
assert (ctx != NULL);
val = stun_bind_process (ctx->bind, buf, len,
(struct sockaddr *)&mapped, &mappedlen);
if (val)
return val;
/* Mapped address mistmatch! (FIXME: what are we really supposed to do
* in this case???) */
if (sockaddrcmp ((struct sockaddr *)&mapped,
(struct sockaddr *)&ctx->mapped))
{
DBG (" Mapped address mismatch! (Symmetric NAT?)\n");
return ECONNREFUSED;
}
val = stun_find_xor_addr (buf, STUN_XOR_INTERNAL_ADDRESS, intad, adlen);
if (val)
{
DBG (" No XOR-INTERNAL-ADDRESS: %s\n", strerror (val));
return val;
}
stun_find32 (buf, STUN_REFRESH_INTERVAL, &ctx->refresh);
/* TODO: give this to caller */
DBG (" Internal address found!\n");
stun_bind_cancel (ctx->bind);
ctx->bind = NULL;
return 0;
}
...@@ -160,6 +160,21 @@ int stun_bind_keepalive (int fd, const struct sockaddr *restrict srv, ...@@ -160,6 +160,21 @@ int stun_bind_keepalive (int fd, const struct sockaddr *restrict srv,
socklen_t srvlen); socklen_t srvlen);
/**
* <b>Provisional</b> and incomplete STUN NAT control API
* Subject to change.
*/
typedef struct stun_nested_s stun_nested_t;
int stun_nested_start (stun_nested_t **restrict context, int fd,
const struct sockaddr *restrict mapad,
const struct sockaddr *restrict natad,
socklen_t adlen, uint32_t refresh);
int stun_nested_process (stun_nested_t *restrict ctx,
const void *restrict buf, size_t len,
struct sockaddr *restrict intad, socklen_t *adlen);
# ifndef STUN_VALIDATE_DECLARATION # ifndef STUN_VALIDATE_DECLARATION
# define STUN_VALIDATE_DECLARATION 2 # define STUN_VALIDATE_DECLARATION 2
......
...@@ -179,6 +179,8 @@ static inline ssize_t stun_recv (int fd, uint8_t *buf, size_t maxlen) ...@@ -179,6 +179,8 @@ static inline ssize_t stun_recv (int fd, uint8_t *buf, size_t maxlen)
return stun_recvfrom (fd, buf, maxlen, NULL, NULL); return stun_recvfrom (fd, buf, maxlen, NULL, NULL);
} }
int sockaddrcmp (const struct sockaddr *a, const struct sockaddr *b);
# ifdef __cplusplus # ifdef __cplusplus
} }
# endif # endif
......
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