Commit 03590520 authored by Youness Alaoui's avatar Youness Alaoui

Fixed tools and binding usage to work with new API

parent 3f3c7e4d
......@@ -13,11 +13,7 @@ include $(top_srcdir)/common.mk
AM_CFLAGS = -std=gnu99 $(ERROR_CFLAGS) $(OPENSSL_CFLAGS)
AM_CPPFLAGS = -I$(top_srcdir)
BUILT_SOURCES = unknown.c
CLEANFILES += $(BUILT_SOURCES)
noinst_LTLIBRARIES = libstun.la
dist_noinst_SCRIPTS = build-unknown.sh
libstun_la_SOURCES = stun.h constants.h \
stunagent.c stunagent.h \
......@@ -25,16 +21,8 @@ libstun_la_SOURCES = stun.h constants.h \
stun3489bis.c stun3489bis.h \
stuncrc32.c stuncrc32.h \
stunhmac.c stunhmac.h \
utils.c utils.h
# usages/timer.h usages/timer.c \
# usages/trans.h usages/trans.c \
# usages/stun-ice.c usages/stun-ice.h \
# usages/bind.c usages/bind.h
utils.c utils.h
# usages/stun-ice.c usages/stun-ice.h
libstun_la_LIBADD = $(OPENSSL_LIBS) $(LIBRT)
unknown.c: stun-msg.h build-unknown.sh
rm -f unknown.c
$(SHELL) "$(srcdir)/build-unknown.sh" < "$(srcdir)/stun-msg.h" > unknown.c
......@@ -62,7 +62,7 @@
#define STUN_MAX_MESSAGE_SIZE_IPV4 576
#define STUN_MAX_MESSAGE_SIZE_IPV6 1280
#define STUN_MAX_MESSAGE_SIZE MAX_STUN_SIZE_IPV4
#define STUN_MAX_MESSAGE_SIZE STUN_MAX_MESSAGE_SIZE_IPV4
#define STUN_ID_LEN 16
......
......@@ -85,6 +85,7 @@ StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg,
uint8_t sha[20];
uint16_t hlen;
int sent_id_idx = -1;
uint16_t unknown;
len = stun_message_validate_buffer_length (buffer, buffer_len);
if (len == STUN_MESSAGE_BUFFER_INVALID) {
......@@ -182,8 +183,8 @@ StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg,
}
if (key != NULL && key_len > 0) {
hash = (uint8_t *) stun_message_find (msg, STUN_ATTRIBUTE_MESSAGE_INTEGRITY,
&hlen);
hash = (uint8_t *) stun_message_find (msg,
STUN_ATTRIBUTE_MESSAGE_INTEGRITY, &hlen);
stun_sha1 (msg->buffer, stun_message_length (msg), sha, key, key_len);
stun_debug (" Message HMAC-SHA1 fingerprint:");
......@@ -206,6 +207,13 @@ StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg,
if (sent_id_idx != -1 && sent_id_idx < STUN_AGENT_MAX_SAVED_IDS) {
agent->sent_ids[sent_id_idx].valid = FALSE;
}
if (stun_agent_find_unknowns (agent, msg, &unknown, 1) > 0) {
if (stun_message_get_class (msg) == STUN_REQUEST)
return STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE;
else
return STUN_VALIDATION_UNKNOWN_ATTRIBUTE;
}
return STUN_VALIDATION_SUCCESS;
}
......@@ -265,7 +273,7 @@ bool stun_agent_init_indication (StunAgent *agent, StunMessage *msg,
bool stun_agent_init_response (StunAgent *agent, StunMessage *msg,
uint8_t *buffer, size_t buffer_len, stun_method_t m, StunMessage *request)
uint8_t *buffer, size_t buffer_len, const StunMessage *request)
{
stun_transid_t id;
......@@ -296,7 +304,7 @@ bool stun_agent_init_response (StunAgent *agent, StunMessage *msg,
bool stun_agent_init_error (StunAgent *agent, StunMessage *msg,
uint8_t *buffer, size_t buffer_len, StunMessage *request,
uint8_t *buffer, size_t buffer_len, const StunMessage *request,
stun_error_t err)
{
stun_transid_t id;
......@@ -330,7 +338,8 @@ bool stun_agent_init_error (StunAgent *agent, StunMessage *msg,
size_t stun_agent_build_unknown_attributes_error (StunAgent *agent,
StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMessage *request)
StunMessage *msg, uint8_t *buffer, size_t buffer_len,
const StunMessage *request)
{
unsigned counter;
......@@ -359,7 +368,7 @@ size_t stun_agent_build_unknown_attributes_error (StunAgent *agent,
size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg,
uint8_t *key, size_t key_len)
const uint8_t *key, size_t key_len)
{
uint8_t *ptr;
uint32_t fpr;
......@@ -374,7 +383,7 @@ size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg,
stun_sha1 (msg->buffer, stun_message_length (msg), ptr, key, key_len);
stun_debug (" Message HMAC-SHA1 fingerprint:"
stun_debug (" Message HMAC-SHA1 message integrity:"
"\n key : ");
stun_debug_bytes (key, key_len);
stun_debug ("\n sent : ");
......@@ -390,8 +399,13 @@ size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg,
return 0;
}
fpr = stun_fingerprint (msg->buffer, stun_message_length (msg));
memcpy (ptr, &fpr, sizeof (fpr));
stun_debug (" Message HMAC-SHA1 fingerprint: ");
stun_debug_bytes (ptr, 4);
stun_debug ("\n");
}
......@@ -401,7 +415,7 @@ size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg,
stun_message_id (msg, id);
memcpy (agent->sent_ids[i].id, id, sizeof(stun_transid_t));
agent->sent_ids[i].method = stun_message_get_method (msg);
agent->sent_ids[i].key = key;
agent->sent_ids[i].key = (uint8_t *) key;
agent->sent_ids[i].key_len = key_len;
agent->sent_ids[i].valid = TRUE;
break;
......@@ -409,7 +423,7 @@ size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg,
}
}
msg->key = key;
msg->key = (uint8_t *) key;
msg->key_len = key_len;
return stun_message_length (msg);
......
......@@ -99,13 +99,14 @@ bool stun_agent_init_request (StunAgent *agent, StunMessage *msg,
bool stun_agent_init_indication (StunAgent *agent, StunMessage *msg,
uint8_t *buffer, size_t buffer_len, stun_method_t m);
bool stun_agent_init_response (StunAgent *agent, StunMessage *msg,
uint8_t *buffer, size_t buffer_len, stun_method_t m, StunMessage *request);
uint8_t *buffer, size_t buffer_len, const StunMessage *request);
bool stun_agent_init_error (StunAgent *agent, StunMessage *msg,
uint8_t *buffer, size_t buffer_len, StunMessage *request,
uint8_t *buffer, size_t buffer_len, const StunMessage *request,
stun_error_t err);
size_t stun_agent_build_unknown_attributes_error (StunAgent *agent,
StunMessage *msg, uint8_t *buffer, size_t buffer_len, StunMessage *request);
StunMessage *msg, uint8_t *buffer, size_t buffer_len,
const StunMessage *request);
size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg,
uint8_t *key, size_t key_len);
const uint8_t *key, size_t key_len);
#endif /* _STUN_AGENT_H */
......@@ -120,5 +120,5 @@ void stun_make_transid (stun_transid_t id)
/* Computes hash out of contentious area */
HMAC (EVP_sha1 (), key, sizeof (key), counter.bytes, sizeof (counter),
sha, NULL);
memcpy (id, sha, 12);
memcpy (id, sha, 16);
}
......@@ -62,7 +62,7 @@ bool stun_message_init (StunMessage *msg, stun_class_t c, stun_method_t m,
stun_set_type (msg->buffer, c, m);
memcpy (msg->buffer + STUN_MESSAGE_TRANS_ID_POS,
id, sizeof (STUN_MESSAGE_TRANS_ID_LEN));
id, STUN_MESSAGE_TRANS_ID_LEN);
return TRUE;
}
......@@ -304,8 +304,7 @@ void *
stun_message_append (StunMessage *msg, stun_attr_type_t type, size_t length)
{
uint8_t *a;
uint16_t mlen = stun_message_length (msg);
uint16_t mlen = stun_message_length (msg) - STUN_MESSAGE_HEADER_LENGTH;
if ((((size_t)mlen) + STUN_ATTRIBUTE_HEADER_LENGTH + length) > msg->buffer_len)
return NULL;
......
......@@ -8,16 +8,21 @@
#
include $(top_srcdir)/common.mk
AM_CFLAGS = -std=gnu99
AM_CPPFLAGS = -I$(top_srcdir)
AM_CPPFLAGS = -I$(top_srcdir)
bin_PROGRAMS = stunbdc stund
check_PROGRAMS = stund
stund_SOURCES = stund.c stund.h
stund_LDADD = ../libstun.la -lpthread
stunbdc_SOURCES = stunbdc.c \
bind.c bind.h \
trans.c trans.h \
timer.c timer.h
stunbdc_LDADD = ../libstun.la
......@@ -41,7 +41,7 @@
#include <sys/socket.h>
#include "bind.h"
#include "stun-msg.h"
#include "stun/stunagent.h"
#include <assert.h>
#include <string.h>
......@@ -60,8 +60,23 @@
struct stun_bind_s
{
stun_trans_t trans;
StunAgent agent;
};
static const uint16_t known_attributes[] = {
STUN_ATTRIBUTE_MAPPED_ADDRESS,
STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
STUN_ATTRIBUTE_XOR_INTERNAL_ADDRESS,
STUN_ATTRIBUTE_FINGERPRINT,
STUN_ATTRIBUTE_ALTERNATE_SERVER,
STUN_ATTRIBUTE_PRIORITY,
STUN_ATTRIBUTE_USE_CANDIDATE,
STUN_ATTRIBUTE_ICE_CONTROLLING,
STUN_ATTRIBUTE_ICE_CONTROLLED,
STUN_ATTRIBUTE_USERNAME,
STUN_ATTRIBUTE_REFRESH_INTERVAL,
0
};
/** Initialization/deinitization */
......@@ -100,8 +115,14 @@ stun_bind_alloc (stun_bind_t **restrict context, int fd,
return val;
}
stun_init_request (ctx->trans.msg.buf, STUN_BINDING);
ctx->trans.msg.length = sizeof (ctx->trans.msg.buf);
stun_agent_init (&ctx->agent, known_attributes,
STUN_COMPATIBILITY_3489BIS,
STUN_AGENT_USAGE_ADD_SERVER);
stun_agent_init_request (&ctx->agent, &ctx->trans.message,
ctx->trans.msg.buf, sizeof (ctx->trans.msg.buf), STUN_BINDING);
ctx->trans.msg.length = ctx->trans.message.buffer_len;
return 0;
}
......@@ -117,9 +138,12 @@ int stun_bind_start (stun_bind_t **restrict context, int fd,
return val;
ctx = *context;
val = stun_finish (ctx->trans.msg.buf, &ctx->trans.msg.length, compat);
if (val)
val = stun_agent_finish_message (&ctx->agent, &ctx->trans.message, NULL, 0);
if (val == 0)
goto error;
ctx->trans.msg.length = val;
val = stun_trans_start (&ctx->trans);
if (val)
......@@ -168,7 +192,7 @@ int stun_bind_process (stun_bind_t *restrict ctx,
assert (ctx != NULL);
val = stun_trans_preprocess (&ctx->trans, &code, buf, len);
val = stun_trans_preprocess (&ctx->agent, &ctx->trans, &code, buf, len);
switch (val)
{
case EAGAIN:
......@@ -176,26 +200,28 @@ int stun_bind_process (stun_bind_t *restrict ctx,
case 0:
break;
default:
if (code == STUN_ROLE_CONFLICT)
if (code == STUN_ERROR_ROLE_CONFLICT)
val = ECONNRESET;
stun_bind_cancel (ctx);
return val;
}
val = stun_find_xor_addr (buf, STUN_XOR_MAPPED_ADDRESS, addr, addrlen);
val = stun_message_find_xor_addr (&ctx->trans.message,
STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, addr, addrlen);
if (val)
{
DBG (" No XOR-MAPPED-ADDRESS: %s\n", strerror (val));
val = stun_find_addr (buf, STUN_MAPPED_ADDRESS, addr, addrlen);
stun_debug (" No XOR-MAPPED-ADDRESS: %s\n", strerror (val));
val = stun_message_find_addr (&ctx->trans.message,
STUN_ATTRIBUTE_MAPPED_ADDRESS, addr, addrlen);
if (val)
{
DBG (" No MAPPED-ADDRESS: %s\n", strerror (val));
stun_debug (" No MAPPED-ADDRESS: %s\n", strerror (val));
stun_bind_cancel (ctx);
return val;
}
}
DBG (" Mapped address found!\n");
stun_debug (" Mapped address found!\n");
stun_bind_cancel (ctx);
return 0;
}
......@@ -208,7 +234,7 @@ int stun_bind_run (int fd,
struct sockaddr *restrict addr, socklen_t *addrlen, int compat)
{
stun_bind_t *ctx;
uint8_t buf[STUN_MAXMSG];
uint8_t buf[STUN_MAX_MESSAGE_SIZE];
ssize_t val;
val = stun_bind_start (&ctx, fd, srv, srvlen, compat);
......@@ -231,7 +257,7 @@ int stun_bind_run (int fd,
return val;
}
#if 0
/** ICE keep-alives (Binding discovery indication!) */
int
......@@ -240,23 +266,26 @@ stun_bind_keepalive (int fd, const struct sockaddr *restrict srv,
{
uint8_t buf[28];
size_t len = sizeof (buf);
int val;
StunAgent agent;
StunMessage msg;
stun_agent_init (&agent, known_attributes,
STUN_COMPATIBILITY_3489BIS,
STUN_AGENT_USAGE_USE_FINGERPRINT);
stun_agent_init_indication (&agent, &msg,
buf, sizeof (buf), STUN_BINDING);
len = stun_agent_finish_message (&agent, &msg, NULL, 0);
stun_init_indication (buf, STUN_BINDING);
val = stun_finish (buf, &len, compat);
assert (val == 0);
(void)val;
assert (len == sizeof(buf));
/* NOTE: hopefully, this is only needed for non-stream sockets */
if (stun_sendto (fd, buf, len, srv, srvlen) == -1)
return errno;
return 0;
}
#endif
/** Connectivity checks */
#include "stun-ice.h"
int
stun_conncheck_start (stun_bind_t **restrict context, int fd,
const struct sockaddr *restrict srv, socklen_t srvlen,
......@@ -290,29 +319,38 @@ stun_conncheck_start (stun_bind_t **restrict context, int fd,
if (compat != 1) {
if (cand_use)
{
val = stun_append_flag (ctx->trans.msg.buf,
sizeof (ctx->trans.msg.buf),
STUN_USE_CANDIDATE);
val = stun_message_append_flag (&ctx->trans.message,
STUN_ATTRIBUTE_USE_CANDIDATE);
if (val)
goto error;
}
val = stun_append32 (ctx->trans.msg.buf, sizeof (ctx->trans.msg.buf),
STUN_PRIORITY, priority);
val = stun_message_append32 (&ctx->trans.message,
STUN_ATTRIBUTE_PRIORITY, priority);
if (val)
goto error;
val = stun_append64 (ctx->trans.msg.buf, sizeof (ctx->trans.msg.buf),
controlling ? STUN_ICE_CONTROLLING
: STUN_ICE_CONTROLLED, tie);
val = stun_message_append64 (&ctx->trans.message,
controlling ? STUN_ATTRIBUTE_ICE_CONTROLLING
: STUN_ATTRIBUTE_ICE_CONTROLLED, tie);
if (val)
goto error;
}
val = stun_finish_short (ctx->trans.msg.buf, &ctx->trans.msg.length,
username, compat == 1 ? NULL : password, NULL, compat);
if (val)
if (username) {
val = stun_message_append_string (&ctx->trans.message,
STUN_ATTRIBUTE_USERNAME, username);
if (val)
goto error;
}
val = stun_agent_finish_message (&ctx->agent, &ctx->trans.message,
compat == 1 ? NULL : (const uint8_t *) password,
compat == 1 ? 0 : strlen (password));
if (val == 0)
goto error;
ctx->trans.msg.length = val;
val = stun_trans_start (&ctx->trans);
if (val)
......@@ -359,15 +397,13 @@ int stun_nested_start (stun_nested_t **restrict context, int fd,
*context = ctx;
val = stun_append32 (ctx->bind->trans.msg.buf,
sizeof (ctx->bind->trans.msg.buf),
STUN_REFRESH_INTERVAL, refresh);
val = stun_message_append32 (&ctx->bind->trans.message,
STUN_ATTRIBUTE_REFRESH_INTERVAL, refresh);
if (val)
goto error;
val = stun_finish (ctx->bind->trans.msg.buf,
&ctx->bind->trans.msg.length,
compat);
val = stun_agent_finish_message (&ctx->bind->agent,
&ctx->bind->trans.message, NULL, 0);
if (val)
goto error;
......@@ -403,21 +439,24 @@ int stun_nested_process (stun_nested_t *restrict ctx,
if (sockaddrcmp ((struct sockaddr *)&mapped,
(struct sockaddr *)&ctx->mapped))
{
DBG (" Mapped address mismatch! (Symmetric NAT?)\n");
stun_debug (" Mapped address mismatch! (Symmetric NAT?)\n");
return ECONNREFUSED;
}
val = stun_find_xor_addr (buf, STUN_XOR_INTERNAL_ADDRESS, intad, adlen);
val = stun_message_find_xor_addr (&ctx->bind->trans.message,
STUN_ATTRIBUTE_XOR_INTERNAL_ADDRESS,
intad, adlen);
if (val)
{
DBG (" No XOR-INTERNAL-ADDRESS: %s\n", strerror (val));
stun_debug (" No XOR-INTERNAL-ADDRESS: %s\n", strerror (val));
return val;
}
stun_find32 (buf, STUN_REFRESH_INTERVAL, &ctx->refresh);
stun_message_find32 (&ctx->bind->trans.message,
STUN_ATTRIBUTE_REFRESH_INTERVAL, &ctx->refresh);
/* TODO: give this to caller */
DBG (" Internal address found!\n");
stun_debug (" Internal address found!\n");
stun_bind_cancel (ctx->bind);
ctx->bind = NULL;
return 0;
......
......@@ -39,7 +39,8 @@
#include <sys/types.h>
#include <sys/socket.h>
#include "stunagent.h"
#include "stun/stunagent.h"
#include "bind.h"
#include <unistd.h>
#include <getopt.h>
......
......@@ -62,9 +62,13 @@
/** Default port for STUN binding discovery */
#define IPPORT_STUN 3478
#include "stun/stun-msg.h"
#include "stun/stunagent.h"
#include "stund.h"
static const uint16_t known_attributes[] = {
0
};
/**
* Creates a listening socket
*/
......@@ -185,12 +189,16 @@ ssize_t send_safe (int fd, const struct msghdr *msg)
}
static int dgram_process (int sock)
static int dgram_process (int sock, StunAgent *agent)
{
struct sockaddr_storage addr;
uint8_t buf[STUN_MAXMSG];
uint8_t buf[STUN_MAX_MESSAGE_SIZE];
char ctlbuf[CMSG_SPACE (sizeof (struct in6_pktinfo))];
struct iovec iov = { buf, sizeof (buf) };
StunMessage request;
StunMessage response;
StunValidationStatus validation;
struct msghdr mh =
{
.msg_name = (struct sockaddr *)&addr,
......@@ -205,37 +213,42 @@ static int dgram_process (int sock)
if (len == (size_t)-1)
return -1;
/* Mal-formatted packets */
if ((stun_validate (buf, len) <= 0)
|| (stun_get_class (buf) != STUN_REQUEST))
return -1;
validation = stun_agent_validate (agent, &request, buf, len, NULL, 0);
/* Unknown attributes */
if (stun_has_unknown (buf))
if (validation == STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE)
{
stun_init_error_unknown (buf, sizeof (buf), buf, 0);
goto finish;
stun_agent_build_unknown_attributes_error (agent, &response, buf,
sizeof (buf), &request);
goto send_buf;
}
/* Mal-formatted packets */
if (validation != STUN_VALIDATION_SUCCESS ||
stun_message_get_class (&request) != STUN_REQUEST) {
return -1;
}
switch (stun_get_method (buf))
switch (stun_message_get_method (&request))
{
case STUN_BINDING:
stun_init_response (buf, sizeof (buf), buf, 0);
if (stun_has_cookie (buf))
stun_append_xor_addr (buf, sizeof (buf),
STUN_XOR_MAPPED_ADDRESS,
stun_agent_init_response (agent, &response, buf, sizeof (buf), &request);
if (stun_has_cookie (&request))
stun_message_append_xor_addr (&response,
STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
mh.msg_name, mh.msg_namelen);
else
stun_append_addr (buf, sizeof (buf), STUN_MAPPED_ADDRESS,
stun_message_append_addr (&response, STUN_ATTRIBUTE_MAPPED_ADDRESS,
mh.msg_name, mh.msg_namelen);
break;
default:
stun_init_error (buf, sizeof (buf), buf, STUN_BAD_REQUEST, 0);
stun_agent_init_error (agent, &response, buf, sizeof (buf),
&request, STUN_ERROR_BAD_REQUEST);
}
finish:
stun_finish (buf, &iov.iov_len, 0);
iov.iov_len = stun_agent_finish_message (agent, &response, NULL, 0);
send_buf:
len = send_safe (sock, &mh);
return (len < iov.iov_len) ? -1 : 0;
......@@ -244,12 +257,17 @@ finish:
static int run (int family, int protocol, unsigned port)
{
StunAgent agent;
int sock = listen_socket (family, SOCK_DGRAM, protocol, htons (port));
if (sock == -1)
return -1;
stun_agent_init (&agent, known_attributes,
STUN_COMPATIBILITY_3489BIS, STUN_AGENT_USAGE_ADD_SERVER);
for (;;)
dgram_process (sock);
dgram_process (sock, &agent);
}
......
......@@ -50,7 +50,7 @@
# include <poll.h>
#endif
#include "stun-msg.h"
#include "stun/stunagent.h"
#include "trans.h"
#define TRANS_OWN_FD 0x1 /* descriptor belongs to us */
......@@ -199,7 +199,7 @@ int stun_trans_start (stun_trans_t *tr)
else
stun_timer_start (&tr->timer);
DBG ("STUN transaction @%p started (timeout: %ums)\n", tr,
stun_debug ("STUN transaction @%p started (timeout: %ums)\n", tr,
stun_trans_timeout (tr));
val = stun_trans_send (tr);
......@@ -324,7 +324,7 @@ int stun_trans_tick (stun_trans_t *tr)
switch (stun_timer_refresh (&tr->timer))
{
case -1:
DBG ("STUN transaction @%p failed: time out.\n", tr);
stun_debug ("STUN transaction @%p failed: time out.\n", tr);
return ETIMEDOUT; // fatal error!
case 0:
......@@ -333,7 +333,7 @@ int stun_trans_tick (stun_trans_t *tr)
tr->msg.offset = 0;
stun_trans_send (tr);
DBG ("STUN transaction @%p retransmitted (timeout: %ums).\n", tr,
stun_debug ("STUN transaction @%p retransmitted (timeout: %ums).\n", tr,
stun_trans_timeout (tr));
}
return EAGAIN;
......@@ -401,27 +401,32 @@ int stun_trans_recv (stun_trans_t *tr, uint8_t *buf, size_t buflen)
int stun_trans_preprocess (stun_trans_t *restrict tr, int *pcode,
const void *restrict buf, size_t len)
int stun_trans_preprocess (StunAgent *agent,
stun_trans_t *restrict tr, int *pcode,
const void *restrict buf, size_t len)
{
StunValidationStatus valid;
assert (pcode != NULL);
/* FIXME: possible infinite loop */
if (stun_validate (buf, len) <= 0)
return EAGAIN;
*pcode = -1;
DBG ("Received %u-bytes STUN message\n",
(unsigned)stun_validate (buf, len));
/* NOTE: currently we ignore unauthenticated messages if the context
* is authenticated, for security reasons. */
valid = stun_agent_validate (agent, &tr->message, buf, len, NULL, NULL);
if (valid == STUN_VALIDATION_UNKNOWN_ATTRIBUTE)
return EPROTO;
if (!stun_match_messages (buf, tr->msg.buf, tr->key.value, tr->key.length,
pcode))
if (valid != STUN_VALIDATION_SUCCESS)
return EAGAIN;
stun_debug ("Received %u-bytes STUN message\n", (unsigned)len);
/* NOTE: currently we ignore unauthenticated messages if the context
* is authenticated, for security reasons. */
if (stun_message_get_class (&tr->message) == STUN_ERROR) {
stun_message_find_error (&tr->message, pcode);
}
if (*pcode >= 0)
{
DBG (" STUN error message received (code: %d)\n", *pcode);
stun_debug (" STUN error message received (code: %d)\n", *pcode);
/* ALTERNATE-SERVER mechanism */
if ((tr->key.value != NULL) && ((*pcode / 100) == 3))
......@@ -429,10 +434,10 @@ int stun_trans_preprocess (stun_trans_t *restrict tr, int *pcode,
struct sockaddr_storage srv;
socklen_t slen = sizeof (srv);
if (stun_find_addr (buf, STUN_ALTERNATE_SERVER,
if (stun_message_find_addr (&tr->message, STUN_ATTRIBUTE_ALTERNATE_SERVER,
(struct sockaddr *)&srv, &slen))
{
DBG (" Unexpectedly missing ALTERNATE-SERVER attribute\n");
stun_debug (" Unexpectedly missing ALTERNATE-SERVER attribute\n");
return ECONNREFUSED;
}
......@@ -441,7 +446,7 @@ int stun_trans_preprocess (stun_trans_t *restrict tr, int *pcode,
if (connect (tr->sock.fd, (struct sockaddr *)&srv, slen))
{
/* This error case includes address family mismatch */
DBG (" Error switching to alternate server: %s\n",
stun_debug (" Error switching to alternate server: %s\n",
strerror (errno));
return ECONNREFUSED;
}
......@@ -451,26 +456,23 @@ int stun_trans_preprocess (stun_trans_t *restrict tr, int *pcode,
if ((tr->sock.dst.ss_family != srv.ss_family)
|| (slen > sizeof (tr->sock.dst)))
{
DBG (" Unsupported alternate server\n");
stun_debug (" Unsupported alternate server\n");
return ECONNREFUSED;
}
memcpy (&tr->sock.dst, &srv, tr->sock.dstlen = slen);
}
DBG (" Restarting with alternate server\n");
stun_debug (" Restarting with alternate server\n");
if (stun_trans_start (tr) == 0)
return EAGAIN;
DBG (" Restart failed!\n");
stun_debug (" Restart failed!\n");
}
return ECONNREFUSED;
}
if (stun_has_unknown (buf))
return EPROTO;
return 0;
}
......
......@@ -45,6 +45,7 @@
# include <sys/socket.h>
# include "timer.h"
#include "stun/stunagent.h"
typedef struct stun_trans_s
{
......@@ -54,8 +55,9 @@ typedef struct stun_trans_s
struct
{
size_t length, offset;
uint8_t buf[STUN_MAXMSG];
uint8_t buf[STUN_MAX_MESSAGE_SIZE];
} msg;
StunMessage message;