Commit ec4f1740 authored by Pekka Pessi's avatar Pekka Pessi

Added hostname resolving to stun. (kv)

2005-10-13  Kai Vehmanen  <kai.vehmanen@nokia.com>

* stun_common.h, stun.h: Updated inline docs to use the doxygen syntax.

* stun_common.c: Fixed memory leaks.

* stun.c (stun_engine_create): Add hostname resolving.

darcs-hash:20051014071243-65a35-497ef1552155b373715da1102cba1da684d61377.gz
parent b9f5aaa2
2005-10-13 Kai Vehmanen <kai.vehmanen@nokia.com>
* stun_common.h, stun.h: Updated inline docs to use
the doxygen syntax.
* stun_common.c: Fixed memory leaks.
* stun.c (stun_engine_create): Add hostname resolving.
2005-07-18 Kai Vehmanen <kai.vehmanen@nokia.com>
* Initial import of the module to Sofia-SIP tree.
......@@ -37,6 +37,8 @@
#include "config.h"
#include <assert.h>
#include "stun.h"
#include <su_alloc.h>
......@@ -81,11 +83,14 @@ struct stun_socket_s
int ss_state;
};
/** Create a STUN engine */
/**
* Creates a STUN engine
*
* @param stun server hostname or IPv4 address
* @param msg_integrity true if msg integr. should be used
**/
stun_engine_t *stun_engine_create(char const *server,
int msg_integrity
/* stun_engine_t *stun_engine_create(struct sockaddr_in *server */
/* other parameters?? */)
int msg_integrity)
{
stun_engine_t *stun;
......@@ -100,7 +105,7 @@ stun_engine_t *stun_engine_create(char const *server,
*/
memset(&stun->stun_srvr4[0], 0, sizeof(stun->stun_srvr4[0]));
if(server) {
stun_atoaddr(&stun->stun_srvr4[0].su_sin, server);
stun_atoaddr((struct sockaddr_in *)&(stun->stun_srvr4[0]), server);
if(stun->stun_srvr4[0].su_sin.sin_port == 0) {
stun->stun_srvr4[0].su_sin.sin_port = htons(STUN_DEFAULT_PORT);
}
......@@ -221,6 +226,8 @@ int stun_bind(stun_socket_t *ss,
break;
}
}
if(!found) {
SU_DEBUG_5(("stun: su_getlocalinfo: %s\n", su_gli_strerror(error)));
return errno = EFAULT, -1;
......@@ -230,6 +237,7 @@ int stun_bind(stun_socket_t *ss,
SU_DEBUG_5(("stun: su_getlocalinfo: %s\n", su_gli_strerror(error)));
return errno = EFAULT, -1;
}
if (res) su_freelocalinfo(res);
}
/* run protocol here... */
......@@ -556,8 +564,10 @@ int stun_bind_test(stun_socket_t *ss, struct sockaddr_in *srvr_addr, struct sock
if(stun_make_binding_req(ss, &bind_req, chg_ip, chg_port)<0)
return retval;
if(stun_send_message(sockfd, srvr_addr, &bind_req, &(ss->ss_engine->password))<0)
if(stun_send_message(sockfd, srvr_addr, &bind_req, &(ss->ss_engine->password))<0) {
stun_free_message(&bind_req);
return retval;
}
FD_ZERO(&rfds);
FD_SET(sockfd, &rfds); /* Set sockfd for read monitoring */
......@@ -578,6 +588,7 @@ int stun_bind_test(stun_socket_t *ss, struct sockaddr_in *srvr_addr, struct sock
z = recvfrom(sockfd, dgram, 512, 0,
(struct sockaddr *)&recv_addr, &recv_addr_len);
if(z<0) {
stun_free_message(&bind_req);
return retval;
}
bind_resp.enc_buf.data = (unsigned char *)malloc(z);
......@@ -589,24 +600,30 @@ int stun_bind_test(stun_socket_t *ss, struct sockaddr_in *srvr_addr, struct sock
else {
SU_DEBUG_3(("Time out no. %d, retransmitting.\n", ++num_retrx));
if(stun_send_message(sockfd, srvr_addr, &bind_req, &(ss->ss_engine->password))<0) {
stun_free_message(&bind_req);
return retval;
}
}
}
if(num_retrx == STUN_MAX_RETRX) {
stun_free_message(&bind_req);
return errno = ETIMEDOUT, retval;
}
/* process response */
if(stun_parse_message(&bind_resp) < 0) {
SU_DEBUG_5(("Error parsing response.\n"));
stun_free_message(&bind_req);
stun_free_message(&bind_req);
return retval;
}
switch(bind_resp.stun_hdr.msg_type) {
case BINDING_RESPONSE:
if(stun_validate_message_integrity(&bind_resp, &ss->ss_engine->password) <0) {
stun_free_message(&bind_req);
stun_free_message(&bind_resp);
return retval;
}
memset(clnt_addr, 0, sizeof(*clnt_addr)); clnt_addr_len = sizeof(*clnt_addr);
......@@ -636,6 +653,9 @@ int stun_bind_test(stun_socket_t *ss, struct sockaddr_in *srvr_addr, struct sock
}
/* return result */
stun_free_message(&bind_resp);
stun_free_message(&bind_req);
return retval;
}
......@@ -764,25 +784,43 @@ int stun_set_uname_pwd(stun_engine_t *se, const unsigned char *uname, int len_un
/* convert character address format to sockaddr_in */
int stun_atoaddr(struct sockaddr_in *addr, char const *in)
{
char *p, tmp[64];
int port_len;
su_addrinfo_t *ai_res = NULL, *ai, hints[1] = {{ 0 }};
char const *host;
char *port, tmp[SU_ADDRSIZE];
int res;
hints->ai_family = AF_INET;
addr->sin_family = AF_INET;
p = strstr(in, ":");
if(p==NULL) {
addr->sin_addr.s_addr = inet_addr(in);
addr->sin_port = 0;
port = strstr(in, ":");
if (port == NULL) {
/* no port specified */
host = in;
}
else {
memcpy(tmp, in, p-in);
tmp[p-in] = '\0';
addr->sin_addr.s_addr = inet_addr(tmp);
port_len = strlen(in)-(p-in)-1;
memcpy(tmp, p+1, port_len);
tmp[port_len] = '\0';
addr->sin_port = htons(atoi(tmp));
assert(port - in < strlen(in) + 1);
memcpy(tmp, in, port - in);
tmp[port - in] = 0;
host = tmp;
++port;
}
return 0;
res = su_getaddrinfo(host, NULL, hints, &ai_res);
for (ai = ai_res;
ai;
ai = ai->ai_next) {
if (ai->ai_family == AF_INET) {
memcpy(addr, ai_res->ai_addr, sizeof(struct sockaddr));
break;
}
}
if (port)
addr->sin_port = htons(atoi(port));
if (ai_res)
su_freeaddrinfo(ai_res);
return res;
}
char const *stun_nattype(stun_engine_t *se)
......
......@@ -28,24 +28,20 @@
*
* @author Tat Chan <Tat.Chan@nokia.com>
* @author Pekka Pessi <Pekka.Pessi@nokia.com>
*
* @date Created: Thu Jul 24 17:08:32 2003 pessi
* @date Last modified: Wed Jul 20 20:35:55 2005 kaiv
* @author Kai Vehmanen <kai.vehmanen@nokia.com>
*/
#include <su_wait.h>
#include "stun_common.h"
#define STUN_LIFETIME_EST 350 /* 6 min? */
#define STUN_LIFETIME_MAX 1800 /* 30 min? */
#define STUN_LIFETIME_CI 5 /* 5 sec confidence interval */
#define STUN_LIFETIME_EST 350 /**< 6 min? */
#define STUN_LIFETIME_MAX 1800 /**< 30 min? */
#define STUN_LIFETIME_CI 5 /**< 5 sec confidence interval */
typedef struct stun_engine_s stun_engine_t;
typedef struct stun_socket_s stun_socket_t;
stun_engine_t *stun_engine_create(char const *server, int use_msgint);
/* stun_engine_t *stun_engine_create(struct sockaddr_in *server); */
void stun_engine_destroy(stun_engine_t *);
......@@ -88,5 +84,4 @@ int stun_atoaddr(struct sockaddr_in *addr, char const *in);
char const *stun_nattype(stun_engine_t *se);
int stun_add_response_address(stun_msg_t *req, struct sockaddr_in *mapped_addr);
#endif /* !defined(STUN_H) */
......@@ -27,6 +27,7 @@
* @brief
*
* @author Tat Chan <Tat.Chan@nokia.com>
* @author Kai Vehmanen <kai.vehmanen@nokia.com>
*
* @date Created: Fri Oct 3 13:40:41 2003 ppessi
*
......@@ -111,6 +112,7 @@ int stun_parse_attribute(stun_msg_t *msg, unsigned char *p) {
p+=2;
attr->attr_type = ntohs(tmp16);
if(attr->attr_type > LARGEST_ATTRIBUTE && attr->attr_type < OPTIONAL_ATTRIBUTE) {
free(attr);
return -1;
}
......@@ -131,16 +133,13 @@ int stun_parse_attribute(stun_msg_t *msg, unsigned char *p) {
case TURN_DESTINATION_ADDRESS:
case TURN_SOURCE_ADDRESS:
#endif
if(stun_parse_attr_address(attr, p, len) < 0)
return -1;
if(stun_parse_attr_address(attr, p, len) < 0) { free(attr); return -1; }
break;
case ERROR_CODE:
if(stun_parse_attr_error_code(attr, p, len) <0)
return -1;
if(stun_parse_attr_error_code(attr, p, len) <0) { free(attr); return -1; }
break;
case UNKNOWN_ATTRIBUTES:
if(stun_parse_attr_unknown_attributes(attr, p, len) <0)
return -1;
if(stun_parse_attr_unknown_attributes(attr, p, len) <0) { free(attr); return -1; }
break;
case CHANGE_REQUEST:
#ifdef USE_TURN
......@@ -148,8 +147,7 @@ int stun_parse_attribute(stun_msg_t *msg, unsigned char *p) {
case TURN_MAGIC_COOKIE:
case TURN_BANDWIDTH:
#endif
if(stun_parse_attr_uint32(attr, p, len) <0)
return -1;
if(stun_parse_attr_uint32(attr, p, len) <0) { free(attr); return -1; }
break;
case USERNAME:
case PASSWORD:
......@@ -157,8 +155,7 @@ int stun_parse_attribute(stun_msg_t *msg, unsigned char *p) {
case TURN_DATA:
case TURN_NONCE:
#endif
if(stun_parse_attr_buffer(attr, p, len) <0)
return -1;
if(stun_parse_attr_buffer(attr, p, len) <0) { free(attr); return -1; }
break;
default:
/* just copy as is */
......@@ -643,12 +640,15 @@ int stun_encode_message(stun_msg_t *msg, stun_buffer_t *pwd) {
if(msg_int) {
/* compute message integrity */
if(stun_encode_message_integrity(msg_int, buf, len, pwd)!=24) {
free(buf);
return -1;
}
memcpy(buf+len, (unsigned char *)msg_int->enc_buf.data, msg_int->enc_buf.size);
}
/* save binary buffer for future reference */
if (msg->enc_buf.data)
free(msg->enc_buf.data);
msg->enc_buf.data = buf; msg->enc_buf.size = buf_len;
}
......
......@@ -85,8 +85,8 @@
#define ERROR_CODE 0x0009
#define UNKNOWN_ATTRIBUTES 0x000a
#define REFLECTED_FROM 0x000b
#define LARGEST_ATTRIBUTE 0x000b /* largest attribute in
the current spec */
#define LARGEST_ATTRIBUTE 0x000b /**< largest attribute in
the current spec */
#define OPTIONAL_ATTRIBUTE 0x7fff
/* Stun response codes */
......@@ -108,7 +108,7 @@
#define STUN_EC_CLASS 0x0070
#define STUN_EC_NUM 0x000F
#define RAND_MAX_16 65535
#define RAND_MAX_16 65535
/* NAT TYPES */
#define STUN_NAT_UNKNOWN 0
......@@ -122,9 +122,9 @@
/* other protocol specific parameters */
#define STUN_MAX_RETRX 8
#define STUN_MAX_RETRX_INT 1600 /* max retrx interval in
millisec */
#define STUN_DEFAULT_PORT 3478
#define STUN_MAX_RETRX_INT 1600 /**< max retrx interval in
millisec */
#define STUN_DEFAULT_PORT 3478 /**< from RFC3489 */
/*
* STUN header format
......@@ -142,29 +142,29 @@
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
struct stun_buffer_s {
unsigned char *data; /**< Pointer to data */
unsigned size; /**< Size of buffer */
unsigned char *data; /**< Pointer to data */
unsigned size; /**< Size of buffer */
};
typedef struct stun_buffer_s stun_buffer_t;
typedef struct {
uint16_t msg_type; /* message type */
uint16_t msg_len; /* message length */
uint16_t tran_id[8]; /* transaction id, 128 bits */
uint16_t msg_type; /**< message type */
uint16_t msg_len; /**< message length */
uint16_t tran_id[8]; /**< transaction id, 128 bits */
} stun_hdr_t;
typedef struct stun_attr_s {
uint16_t attr_type; /* attribute type */
void *pattr; /* pointer to corresponding attribute */
stun_buffer_t enc_buf; /* encoded attribue */
struct stun_attr_s *next; /* next attribute */
uint16_t attr_type; /**< attribute type */
void *pattr; /**< pointer to corresponding attribute */
stun_buffer_t enc_buf; /**< encoded attribue */
struct stun_attr_s *next; /**< next attribute */
} stun_attr_t;
typedef struct {
stun_hdr_t stun_hdr;
stun_attr_t *stun_attr;
stun_buffer_t enc_buf; /* to store already encoded stun msg */
stun_buffer_t enc_buf; /**< to store already encoded stun msg */
} stun_msg_t;
/* stun attribute definition */
......
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