summaryrefslogtreecommitdiffstats
path: root/tinyNET/src
diff options
context:
space:
mode:
Diffstat (limited to 'tinyNET/src')
-rwxr-xr-xtinyNET/src/dhcp/tnet_dhcp.c420
-rwxr-xr-xtinyNET/src/dhcp/tnet_dhcp.h48
-rwxr-xr-xtinyNET/src/dhcp/tnet_dhcp_message.c517
-rwxr-xr-xtinyNET/src/dhcp/tnet_dhcp_message.h257
-rwxr-xr-xtinyNET/src/dhcp/tnet_dhcp_option.c399
-rwxr-xr-xtinyNET/src/dhcp/tnet_dhcp_option.h398
-rwxr-xr-xtinyNET/src/dhcp/tnet_dhcp_option_sip.c159
-rwxr-xr-xtinyNET/src/dhcp/tnet_dhcp_option_sip.h29
-rwxr-xr-xtinyNET/src/dhcp6/tnet_dhcp6.c364
-rwxr-xr-xtinyNET/src/dhcp6/tnet_dhcp6.h35
-rwxr-xr-xtinyNET/src/dhcp6/tnet_dhcp6_duid.c307
-rwxr-xr-xtinyNET/src/dhcp6/tnet_dhcp6_duid.h131
-rwxr-xr-xtinyNET/src/dhcp6/tnet_dhcp6_message.c130
-rwxr-xr-xtinyNET/src/dhcp6/tnet_dhcp6_message.h152
-rwxr-xr-xtinyNET/src/dhcp6/tnet_dhcp6_option.c377
-rwxr-xr-xtinyNET/src/dhcp6/tnet_dhcp6_option.h209
-rwxr-xr-xtinyNET/src/dns/tnet_dns.c1174
-rwxr-xr-xtinyNET/src/dns/tnet_dns.h50
-rwxr-xr-xtinyNET/src/dns/tnet_dns_a.c89
-rwxr-xr-xtinyNET/src/dns/tnet_dns_a.h19
-rwxr-xr-xtinyNET/src/dns/tnet_dns_aaaa.c91
-rwxr-xr-xtinyNET/src/dns/tnet_dns_aaaa.h17
-rwxr-xr-xtinyNET/src/dns/tnet_dns_cname.c77
-rwxr-xr-xtinyNET/src/dns/tnet_dns_cname.h19
-rwxr-xr-xtinyNET/src/dns/tnet_dns_message.c497
-rwxr-xr-xtinyNET/src/dns/tnet_dns_message.h137
-rwxr-xr-xtinyNET/src/dns/tnet_dns_mx.c83
-rwxr-xr-xtinyNET/src/dns/tnet_dns_mx.h21
-rwxr-xr-xtinyNET/src/dns/tnet_dns_naptr.c171
-rwxr-xr-xtinyNET/src/dns/tnet_dns_naptr.h31
-rwxr-xr-xtinyNET/src/dns/tnet_dns_ns.c77
-rwxr-xr-xtinyNET/src/dns/tnet_dns_ns.h19
-rwxr-xr-xtinyNET/src/dns/tnet_dns_opt.c73
-rwxr-xr-xtinyNET/src/dns/tnet_dns_opt.h11
-rwxr-xr-xtinyNET/src/dns/tnet_dns_ptr.c77
-rwxr-xr-xtinyNET/src/dns/tnet_dns_ptr.h19
-rwxr-xr-xtinyNET/src/dns/tnet_dns_regexp.c477
-rwxr-xr-xtinyNET/src/dns/tnet_dns_regexp.h6
-rwxr-xr-xtinyNET/src/dns/tnet_dns_resolvconf.c510
-rwxr-xr-xtinyNET/src/dns/tnet_dns_resolvconf.h6
-rwxr-xr-xtinyNET/src/dns/tnet_dns_rr.c544
-rwxr-xr-xtinyNET/src/dns/tnet_dns_rr.h185
-rwxr-xr-xtinyNET/src/dns/tnet_dns_soa.c113
-rwxr-xr-xtinyNET/src/dns/tnet_dns_soa.h31
-rwxr-xr-xtinyNET/src/dns/tnet_dns_srv.c147
-rwxr-xr-xtinyNET/src/dns/tnet_dns_srv.h21
-rwxr-xr-xtinyNET/src/dns/tnet_dns_txt.c77
-rwxr-xr-xtinyNET/src/dns/tnet_dns_txt.h19
-rwxr-xr-xtinyNET/src/ice/tnet_ice.c6
-rwxr-xr-xtinyNET/src/ice/tnet_ice.h6
-rwxr-xr-xtinyNET/src/ice/tnet_ice_candidate.c383
-rwxr-xr-xtinyNET/src/ice/tnet_ice_candidate.h92
-rwxr-xr-xtinyNET/src/ice/tnet_ice_ctx.c947
-rwxr-xr-xtinyNET/src/ice/tnet_ice_ctx.h40
-rwxr-xr-xtinyNET/src/ice/tnet_ice_event.c23
-rwxr-xr-xtinyNET/src/ice/tnet_ice_event.h58
-rwxr-xr-xtinyNET/src/ice/tnet_ice_pair.c1136
-rwxr-xr-xtinyNET/src/ice/tnet_ice_pair.h60
-rwxr-xr-xtinyNET/src/ice/tnet_ice_utils.c230
-rwxr-xr-xtinyNET/src/ice/tnet_ice_utils.h4
-rwxr-xr-xtinyNET/src/stun/tnet_stun_attr.c996
-rwxr-xr-xtinyNET/src/stun/tnet_stun_pkt.c1245
-rwxr-xr-xtinyNET/src/stun/tnet_stun_types.h20
-rwxr-xr-xtinyNET/src/tinynet.h6
-rwxr-xr-xtinyNET/src/tinynet_config.h10
-rwxr-xr-xtinyNET/src/tls/tnet_dtls.c1166
-rwxr-xr-xtinyNET/src/tls/tnet_dtls.h23
-rwxr-xr-xtinyNET/src/tls/tnet_tls.c475
-rwxr-xr-xtinyNET/src/tls/tnet_tls.h6
-rwxr-xr-xtinyNET/src/tnet.c116
-rwxr-xr-xtinyNET/src/tnet.h6
-rwxr-xr-xtinyNET/src/tnet_auth.c6
-rwxr-xr-xtinyNET/src/tnet_auth.h6
-rwxr-xr-xtinyNET/src/tnet_endianness.c61
-rwxr-xr-xtinyNET/src/tnet_endianness.h6
-rwxr-xr-xtinyNET/src/tnet_hardwares.h41
-rwxr-xr-xtinyNET/src/tnet_nat.c380
-rwxr-xr-xtinyNET/src/tnet_nat.h4
-rwxr-xr-xtinyNET/src/tnet_poll.c132
-rwxr-xr-xtinyNET/src/tnet_poll.h11
-rwxr-xr-xtinyNET/src/tnet_proto.h301
-rwxr-xr-xtinyNET/src/tnet_proxy_node_socks_plugin.c291
-rwxr-xr-xtinyNET/src/tnet_proxy_plugin.c152
-rwxr-xr-xtinyNET/src/tnet_proxy_plugin.h16
-rwxr-xr-xtinyNET/src/tnet_proxydetect.c40
-rwxr-xr-xtinyNET/src/tnet_proxydetect.h14
-rwxr-xr-xtinyNET/src/tnet_socket.c309
-rwxr-xr-xtinyNET/src/tnet_socket.h112
-rwxr-xr-xtinyNET/src/tnet_transport.c391
-rwxr-xr-xtinyNET/src/tnet_transport.h131
-rwxr-xr-xtinyNET/src/tnet_transport_cfsocket.c696
-rwxr-xr-xtinyNET/src/tnet_transport_poll.c1321
-rwxr-xr-xtinyNET/src/tnet_transport_win32.c1227
-rwxr-xr-xtinyNET/src/tnet_types.h72
-rwxr-xr-xtinyNET/src/tnet_utils.c916
-rwxr-xr-xtinyNET/src/tnet_utils.h40
-rwxr-xr-xtinyNET/src/turn/tnet_turn.c72
-rwxr-xr-xtinyNET/src/turn/tnet_turn.h12
-rwxr-xr-xtinyNET/src/turn/tnet_turn_attribute.c56
-rwxr-xr-xtinyNET/src/turn/tnet_turn_attribute.h10
-rwxr-xr-xtinyNET/src/turn/tnet_turn_message.c16
-rwxr-xr-xtinyNET/src/turn/tnet_turn_message.h6
-rwxr-xr-xtinyNET/src/turn/tnet_turn_session.c3460
-rwxr-xr-xtinyNET/src/turn/tnet_turn_session.h47
104 files changed, 13091 insertions, 13138 deletions
diff --git a/tinyNET/src/dhcp/tnet_dhcp.c b/tinyNET/src/dhcp/tnet_dhcp.c
index efd57c5..80a1150 100755
--- a/tinyNET/src/dhcp/tnet_dhcp.c
+++ b/tinyNET/src/dhcp/tnet_dhcp.c
@@ -47,7 +47,7 @@
*/
tnet_dhcp_ctx_t* tnet_dhcp_ctx_create()
{
- return tsk_object_new(tnet_dhcp_ctx_def_t);
+ return tsk_object_new(tnet_dhcp_ctx_def_t);
}
/**@ingroup tnet_dhcp_group
@@ -55,7 +55,7 @@ tnet_dhcp_ctx_t* tnet_dhcp_ctx_create()
*/
tnet_dhcp_params_t* tnet_dhcp_params_create()
{
- return tsk_object_new(tnet_dhcp_params_def_t);
+ return tsk_object_new(tnet_dhcp_params_def_t);
}
/* FIXME: USE retransmission mech (*2*2...)
@@ -64,189 +64,191 @@ tnet_dhcp_params_t* tnet_dhcp_params_create()
*/
tnet_dhcp_reply_t* tnet_dhcp_send_request(tnet_dhcp_ctx_t* ctx, tnet_dhcp_request_t* request)
{
- tsk_buffer_t *output;
- tnet_dhcp_reply_t* reply = tsk_null;
- int ret;
- struct timeval tv;
- fd_set set;
- uint64_t timeout = 0;
- tsk_list_item_t *item;
- const tnet_interface_t *iface;
-
- tnet_socket_t *localsocket4 = tsk_null;
- struct sockaddr_storage server;
-
- if (!ctx || !request){
- goto bail;
- }
-
- localsocket4 = tnet_socket_create(TNET_SOCKET_HOST_ANY, ctx->port_client, tnet_socket_type_udp_ipv4);
- if (!TNET_SOCKET_IS_VALID(localsocket4)){
- TSK_DEBUG_ERROR("Failed to create/bind DHCP client socket.");
- goto bail;
- }
-
- /* Always wait for 200ms before retransmission */
- tv.tv_sec = 0;
- tv.tv_usec = (200 * 1000);
-
- if (tnet_sockaddr_init("255.255.255.255", ctx->server_port, tnet_socket_type_udp_ipv4, &server)){
- TNET_PRINT_LAST_ERROR("Failed to initialize the DHCP server address");
- goto bail;
- }
-
- /* ENABLE BROADCASTING */
- {
+ tsk_buffer_t *output;
+ tnet_dhcp_reply_t* reply = tsk_null;
+ int ret;
+ struct timeval tv;
+ fd_set set;
+ uint64_t timeout = 0;
+ tsk_list_item_t *item;
+ const tnet_interface_t *iface;
+
+ tnet_socket_t *localsocket4 = tsk_null;
+ struct sockaddr_storage server;
+
+ if (!ctx || !request) {
+ goto bail;
+ }
+
+ localsocket4 = tnet_socket_create(TNET_SOCKET_HOST_ANY, ctx->port_client, tnet_socket_type_udp_ipv4);
+ if (!TNET_SOCKET_IS_VALID(localsocket4)) {
+ TSK_DEBUG_ERROR("Failed to create/bind DHCP client socket.");
+ goto bail;
+ }
+
+ /* Always wait for 200ms before retransmission */
+ tv.tv_sec = 0;
+ tv.tv_usec = (200 * 1000);
+
+ if (tnet_sockaddr_init("255.255.255.255", ctx->server_port, tnet_socket_type_udp_ipv4, &server)) {
+ TNET_PRINT_LAST_ERROR("Failed to initialize the DHCP server address");
+ goto bail;
+ }
+
+ /* ENABLE BROADCASTING */
+ {
#if defined(SOLARIS)
- char yes = '1';
+ char yes = '1';
#else
- int yes = 1;
+ int yes = 1;
#endif
- if (setsockopt(localsocket4->fd, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(int))){
- TNET_PRINT_LAST_ERROR("Failed to enable broadcast option");
- goto bail;
- }
- }
-
- /* Set timeout */
- timeout = tsk_time_now() + ctx->timeout;
-
- do
- {
- /* RFC 2131 - 3.6 Use of DHCP in clients with multiple interfaces
- A client with multiple network interfaces must use DHCP through each
- interface independently to obtain configuration information
- parameters for those separate interfaces.
- */
-
- tsk_list_foreach(item, ctx->interfaces){
- iface = item->data;
-
- /* Set FD */
- FD_ZERO(&set);
- FD_SET(localsocket4->fd, &set);
-
- /* ciaddr */
- if (request->type == dhcp_type_inform){
- struct sockaddr_storage ss;
- if (!tnet_getsockname(localsocket4->fd, &ss)){
- uint32_t addr = (uint32_t)tnet_htonl_2(&((struct sockaddr_in*)&ss)->sin_addr);
- memcpy(&request->ciaddr, &addr, 4);
- }
- }
-
- /* chaddr */
- memset(request->chaddr, 0, sizeof(request->chaddr));
- request->hlen = (uint8_t)(iface->mac_address_length > sizeof(request->chaddr) ? sizeof(request->chaddr) : iface->mac_address_length);
- memcpy(request->chaddr, iface->mac_address, request->hlen);
-
- /* Serialize and send to the server. */
- if (!(output = tnet_dhcp_message_serialize(ctx, request))){
- TSK_DEBUG_ERROR("Failed to serialize the DHCP message.");
- goto next_iface;
- }
- /* Send the request to the DHCP server */
- if ((ret = tnet_sockfd_sendto(localsocket4->fd, (const struct sockaddr*)&server, output->data, output->size)) < 0){
- TNET_PRINT_LAST_ERROR("Failed to send DHCP request");
-
- tsk_thread_sleep(150); // wait 150ms before trying the next iface.
- goto next_iface;
- }
- /* wait for response */
- if ((ret = select(localsocket4->fd + 1, &set, NULL, NULL, &tv)) < 0){ /* Error */
- TNET_PRINT_LAST_ERROR("select have failed.");
- tsk_thread_sleep(150); // wait 150ms before trying the next iface.
- goto next_iface;
- }
- else if (ret == 0)
- { /* timeout ==> do nothing */
- }
- else
- { /* there is data to read */
- unsigned int len = 0;
- void* data = tsk_null;
-
- /* Check how how many bytes are pending */
- if ((ret = tnet_ioctlt(localsocket4->fd, FIONREAD, &len)) < 0){
- goto next_iface;
- }
-
- /* Receive pending data */
- data = tsk_calloc(len, sizeof(uint8_t));
- if ((ret = tnet_sockfd_recv(localsocket4->fd, data, len, 0)) < 0){
- TSK_FREE(data);
-
- TNET_PRINT_LAST_ERROR("Failed to receive DHCP dgrams.");
- goto next_iface;
- }
-
- /* Parse the incoming response. */
- reply = tnet_dhcp_message_deserialize(ctx, data, (tsk_size_t)ret);
- TSK_FREE(data);
-
- if (reply)
- { /* response successfuly parsed */
- if (request->xid != reply->xid)
- { /* Not same transaction id ==> continue*/
- TSK_OBJECT_SAFE_FREE(reply);
- }
- }
- }
-
- next_iface:
- TSK_OBJECT_SAFE_FREE(output);
- if (reply){
- goto bail;
- }
- }
- //break;//FIXME
- } while (timeout > tsk_time_epoch());
+ if (setsockopt(localsocket4->fd, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(int))) {
+ TNET_PRINT_LAST_ERROR("Failed to enable broadcast option");
+ goto bail;
+ }
+ }
+
+ /* Set timeout */
+ timeout = tsk_time_now() + ctx->timeout;
+
+ do {
+ /* RFC 2131 - 3.6 Use of DHCP in clients with multiple interfaces
+ A client with multiple network interfaces must use DHCP through each
+ interface independently to obtain configuration information
+ parameters for those separate interfaces.
+ */
+
+ tsk_list_foreach(item, ctx->interfaces) {
+ iface = item->data;
+
+ /* Set FD */
+ FD_ZERO(&set);
+ FD_SET(localsocket4->fd, &set);
+
+ /* ciaddr */
+ if (request->type == dhcp_type_inform) {
+ struct sockaddr_storage ss;
+ if (!tnet_getsockname(localsocket4->fd, &ss)) {
+ uint32_t addr = (uint32_t)tnet_htonl_2(&((struct sockaddr_in*)&ss)->sin_addr);
+ memcpy(&request->ciaddr, &addr, 4);
+ }
+ }
+
+ /* chaddr */
+ memset(request->chaddr, 0, sizeof(request->chaddr));
+ request->hlen = (uint8_t)(iface->mac_address_length > sizeof(request->chaddr) ? sizeof(request->chaddr) : iface->mac_address_length);
+ memcpy(request->chaddr, iface->mac_address, request->hlen);
+
+ /* Serialize and send to the server. */
+ if (!(output = tnet_dhcp_message_serialize(ctx, request))) {
+ TSK_DEBUG_ERROR("Failed to serialize the DHCP message.");
+ goto next_iface;
+ }
+ /* Send the request to the DHCP server */
+ if ((ret = tnet_sockfd_sendto(localsocket4->fd, (const struct sockaddr*)&server, output->data, output->size)) < 0) {
+ TNET_PRINT_LAST_ERROR("Failed to send DHCP request");
+
+ tsk_thread_sleep(150); // wait 150ms before trying the next iface.
+ goto next_iface;
+ }
+ /* wait for response */
+ if ((ret = select(localsocket4->fd + 1, &set, NULL, NULL, &tv)) < 0) { /* Error */
+ TNET_PRINT_LAST_ERROR("select have failed.");
+ tsk_thread_sleep(150); // wait 150ms before trying the next iface.
+ goto next_iface;
+ }
+ else if (ret == 0) {
+ /* timeout ==> do nothing */
+ }
+ else {
+ /* there is data to read */
+ unsigned int len = 0;
+ void* data = tsk_null;
+
+ /* Check how how many bytes are pending */
+ if ((ret = tnet_ioctlt(localsocket4->fd, FIONREAD, &len)) < 0) {
+ goto next_iface;
+ }
+
+ /* Receive pending data */
+ data = tsk_calloc(len, sizeof(uint8_t));
+ if ((ret = tnet_sockfd_recv(localsocket4->fd, data, len, 0)) < 0) {
+ TSK_FREE(data);
+
+ TNET_PRINT_LAST_ERROR("Failed to receive DHCP dgrams.");
+ goto next_iface;
+ }
+
+ /* Parse the incoming response. */
+ reply = tnet_dhcp_message_deserialize(ctx, data, (tsk_size_t)ret);
+ TSK_FREE(data);
+
+ if (reply) {
+ /* response successfuly parsed */
+ if (request->xid != reply->xid) {
+ /* Not same transaction id ==> continue*/
+ TSK_OBJECT_SAFE_FREE(reply);
+ }
+ }
+ }
+
+next_iface:
+ TSK_OBJECT_SAFE_FREE(output);
+ if (reply) {
+ goto bail;
+ }
+ }
+ //break;//FIXME
+ }
+ while (timeout > tsk_time_epoch());
bail:
- TSK_OBJECT_SAFE_FREE(localsocket4);
+ TSK_OBJECT_SAFE_FREE(localsocket4);
- return reply;
+ return reply;
}
/**@ingroup tnet_dhcp_group
*/
tnet_dhcp_reply_t* tnet_dhcp_query(tnet_dhcp_ctx_t* ctx, tnet_dhcp_message_type_t type, tnet_dhcp_params_t* params)
{
- tnet_dhcp_reply_t* reply = tsk_null;
- tnet_dhcp_request_t* request = tnet_dhcp_request_create();
+ tnet_dhcp_reply_t* reply = tsk_null;
+ tnet_dhcp_request_t* request = tnet_dhcp_request_create();
- if (!ctx || !params || !request){
- goto bail;
- }
+ if (!ctx || !params || !request) {
+ goto bail;
+ }
- request->type = type;
- tnet_dhcp_message_add_codes(request, params->codes, params->codes_count);
+ request->type = type;
+ tnet_dhcp_message_add_codes(request, params->codes, params->codes_count);
- reply = tnet_dhcp_send_request(ctx, request);
+ reply = tnet_dhcp_send_request(ctx, request);
bail:
- TSK_OBJECT_SAFE_FREE(request);
+ TSK_OBJECT_SAFE_FREE(request);
- return reply;
+ return reply;
}
/**@ingroup tnet_dhcp_group
*/
int tnet_dhcp_params_add_code(tnet_dhcp_params_t* params, tnet_dhcp_option_code_t code)
{
- if (params){
- if (params->codes_count < TNET_DHCP_MAX_CODES){
- unsigned i;
- for (i = 0; i < params->codes_count; i++){
- if (params->codes[i] == code){
- return -3;
- }
- }
- params->codes[params->codes_count++] = code;
- }
- else return -2;
- }
- return -1;
+ if (params) {
+ if (params->codes_count < TNET_DHCP_MAX_CODES) {
+ unsigned i;
+ for (i = 0; i < params->codes_count; i++) {
+ if (params->codes[i] == code) {
+ return -3;
+ }
+ }
+ params->codes[params->codes_count++] = code;
+ }
+ else {
+ return -2;
+ }
+ }
+ return -1;
}
@@ -256,49 +258,48 @@ int tnet_dhcp_params_add_code(tnet_dhcp_params_t* params, tnet_dhcp_option_code_
//
static tsk_object_t* tnet_dhcp_ctx_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp_ctx_t *ctx = self;
- if (ctx){
- tnet_host_t host;
-
- ctx->vendor_id = tsk_strdup(TNET_DHCP_VENDOR_ID_DEFAULT);
- if (!tnet_gethostname(&host)){
- ctx->hostname = tsk_strndup(host, tsk_strlen(host));
- }
- ctx->timeout = TNET_DHCP_TIMEOUT_DEFAULT;
- ctx->max_msg_size = TNET_DHCP_MAX_MSG_SIZE;
- ctx->port_client = TNET_DHCP_CLIENT_PORT;
- ctx->server_port = TNET_DHCP_SERVER_PORT;
- ctx->interfaces = tnet_get_interfaces();
-
- if (!ctx->interfaces || TSK_LIST_IS_EMPTY(ctx->interfaces)){
- TSK_DEBUG_ERROR("Failed to retrieve network interfaces.");
- }
-
- tsk_safeobj_init(ctx);
- }
- return self;
+ tnet_dhcp_ctx_t *ctx = self;
+ if (ctx) {
+ tnet_host_t host;
+
+ ctx->vendor_id = tsk_strdup(TNET_DHCP_VENDOR_ID_DEFAULT);
+ if (!tnet_gethostname(&host)) {
+ ctx->hostname = tsk_strndup(host, tsk_strlen(host));
+ }
+ ctx->timeout = TNET_DHCP_TIMEOUT_DEFAULT;
+ ctx->max_msg_size = TNET_DHCP_MAX_MSG_SIZE;
+ ctx->port_client = TNET_DHCP_CLIENT_PORT;
+ ctx->server_port = TNET_DHCP_SERVER_PORT;
+ ctx->interfaces = tnet_get_interfaces();
+
+ if (!ctx->interfaces || TSK_LIST_IS_EMPTY(ctx->interfaces)) {
+ TSK_DEBUG_ERROR("Failed to retrieve network interfaces.");
+ }
+
+ tsk_safeobj_init(ctx);
+ }
+ return self;
}
static tsk_object_t* tnet_dhcp_ctx_dtor(tsk_object_t * self)
{
- tnet_dhcp_ctx_t *ctx = self;
- if (ctx){
- tsk_safeobj_deinit(ctx);
+ tnet_dhcp_ctx_t *ctx = self;
+ if (ctx) {
+ tsk_safeobj_deinit(ctx);
- TSK_FREE(ctx->vendor_id);
- TSK_FREE(ctx->hostname);
+ TSK_FREE(ctx->vendor_id);
+ TSK_FREE(ctx->hostname);
- TSK_OBJECT_SAFE_FREE(ctx->interfaces);
- }
- return self;
+ TSK_OBJECT_SAFE_FREE(ctx->interfaces);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp_ctx_def_s =
-{
- sizeof(tnet_dhcp_ctx_t),
- tnet_dhcp_ctx_ctor,
- tnet_dhcp_ctx_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp_ctx_def_s = {
+ sizeof(tnet_dhcp_ctx_t),
+ tnet_dhcp_ctx_ctor,
+ tnet_dhcp_ctx_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp_ctx_def_t = &tnet_dhcp_ctx_def_s;
@@ -307,25 +308,24 @@ const tsk_object_def_t *tnet_dhcp_ctx_def_t = &tnet_dhcp_ctx_def_s;
//
static tsk_object_t* tnet_dhcp_params_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp_params_t *params = self;
- if (params){
- }
- return self;
+ tnet_dhcp_params_t *params = self;
+ if (params) {
+ }
+ return self;
}
static tsk_object_t* tnet_dhcp_params_dtor(tsk_object_t * self)
{
- tnet_dhcp_params_t *params = self;
- if (params){
- }
- return self;
+ tnet_dhcp_params_t *params = self;
+ if (params) {
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp_params_def_s =
-{
- sizeof(tnet_dhcp_params_t),
- tnet_dhcp_params_ctor,
- tnet_dhcp_params_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp_params_def_s = {
+ sizeof(tnet_dhcp_params_t),
+ tnet_dhcp_params_ctor,
+ tnet_dhcp_params_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp_params_def_t = &tnet_dhcp_params_def_s;
diff --git a/tinyNET/src/dhcp/tnet_dhcp.h b/tinyNET/src/dhcp/tnet_dhcp.h
index 9572641..0751914 100755
--- a/tinyNET/src/dhcp/tnet_dhcp.h
+++ b/tinyNET/src/dhcp/tnet_dhcp.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -42,8 +42,8 @@
TNET_BEGIN_DECLS
-/**@ingroup tnet_dhcp_group
-* Default timeout (in milliseconds) value for DHCP requests.
+/**@ingroup tnet_dhcp_group
+* Default timeout (in milliseconds) value for DHCP requests.
*/
#define TNET_DHCP_TIMEOUT_DEFAULT 2000
@@ -70,32 +70,30 @@ TNET_BEGIN_DECLS
/**@ingroup tnet_dhcp_group
* Parameter Request List (55)
*/
-typedef struct tnet_dhcp_params_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_dhcp_params_s {
+ TSK_DECLARE_OBJECT;
- tnet_dhcp_option_code_t codes[TNET_DHCP_MAX_CODES];
- unsigned codes_count;
+ tnet_dhcp_option_code_t codes[TNET_DHCP_MAX_CODES];
+ unsigned codes_count;
}
tnet_dhcp_params_t;
/**@ingroup tnet_dhcp_group
*/
-typedef struct tnet_dhcp_ctx_s
-{
- TSK_DECLARE_OBJECT;
-
- char* vendor_id;
- char* hostname;
- uint16_t max_msg_size; /**< Option code 57. */
-
- uint64_t timeout;
-
- tnet_port_t port_client; /**< Local port to bind to for incloming DHCP messages. Default: 68 */
- tnet_port_t server_port; /**< Destination port for outgoing DHCP messages. Default: 64 */
- tnet_interfaces_L_t *interfaces;
-
- TSK_DECLARE_SAFEOBJ;
+typedef struct tnet_dhcp_ctx_s {
+ TSK_DECLARE_OBJECT;
+
+ char* vendor_id;
+ char* hostname;
+ uint16_t max_msg_size; /**< Option code 57. */
+
+ uint64_t timeout;
+
+ tnet_port_t port_client; /**< Local port to bind to for incloming DHCP messages. Default: 68 */
+ tnet_port_t server_port; /**< Destination port for outgoing DHCP messages. Default: 64 */
+ tnet_interfaces_L_t *interfaces;
+
+ TSK_DECLARE_SAFEOBJ;
}
tnet_dhcp_ctx_t;
diff --git a/tinyNET/src/dhcp/tnet_dhcp_message.c b/tinyNET/src/dhcp/tnet_dhcp_message.c
index 005327d..3e24474 100755
--- a/tinyNET/src/dhcp/tnet_dhcp_message.c
+++ b/tinyNET/src/dhcp/tnet_dhcp_message.c
@@ -35,278 +35,276 @@
tnet_dhcp_message_t* tnet_dhcp_message_create(tnet_dhcp_message_op_t opcode)
{
- return tsk_object_new(tnet_dhcp_message_def_t, opcode);
+ return tsk_object_new(tnet_dhcp_message_def_t, opcode);
}
tnet_dhcp_request_t* tnet_dhcp_request_create()
{
- return tnet_dhcp_message_create(dhcp_op_bootrequest);
+ return tnet_dhcp_message_create(dhcp_op_bootrequest);
}
tnet_dhcp_message_t* tnet_dhcp_reply_create()
{
- return tnet_dhcp_message_create(dhcp_op_bootreply);
+ return tnet_dhcp_message_create(dhcp_op_bootreply);
}
tsk_buffer_t* tnet_dhcp_message_serialize(const tnet_dhcp_ctx_t *ctx, const tnet_dhcp_message_t *message)
{
- tsk_buffer_t* output = 0;
- uint8_t _1byte;
- uint16_t _2bytes;
- uint32_t _4bytes;
-
- /* Check message validity */
- if (!message){
- goto bail;
- }
-
- output = tsk_buffer_create_null();
-
- /*== OP HTYPE HLEN HOPS */
- _4bytes = (((uint32_t)(message->op)) << 24) |
- (((uint32_t)(message->htype)) << 16) |
- (((uint16_t)(message->hlen)) << 8) | message->hops;
- _4bytes = (uint32_t)tnet_ntohl(_4bytes);
- tsk_buffer_append(output, &(_4bytes), 4);
-
- /*== XID */
- _4bytes = (uint32_t)tnet_ntohl(message->xid);
- tsk_buffer_append(output, &(_4bytes), 4);
- /*== SECS */
- _2bytes = tnet_ntohs(message->secs);
- tsk_buffer_append(output, &(_2bytes), 2);
- /*== FLAGS */
- _2bytes = tnet_ntohs(message->flags);
- tsk_buffer_append(output, &(_2bytes), 2);
- /*== CIADDR */
- _4bytes = (uint32_t)tnet_ntohl(message->ciaddr);
- tsk_buffer_append(output, &(_4bytes), 4);
- /*== YIADDR */
- _4bytes = (uint32_t)tnet_ntohl(message->yiaddr);
- tsk_buffer_append(output, &(_4bytes), 4);
- /*== SIADDR */
- _4bytes = (uint32_t)tnet_ntohl(message->siaddr);
- tsk_buffer_append(output, &(_4bytes), 4);
- /*== GIADDR */
- _4bytes = (uint32_t)tnet_ntohl(message->giaddr);
- tsk_buffer_append(output, &(_4bytes), 4);
- /*== CHADDR */
- tsk_buffer_append(output, message->chaddr, sizeof(message->chaddr));
- /*== sname (unused) */
- tsk_buffer_append(output, message->sname, sizeof(message->sname));
- /*== file (unused) */
- tsk_buffer_append(output, message->file, sizeof(message->file));
- /*== Magic Cookie */
- _4bytes = (uint32_t)tnet_ntohl(TNET_DHCP_MAGIC_COOKIE);
- tsk_buffer_append(output, &(_4bytes), 4);
-
- /*== Message Type (option 53)
- */
- tnet_dhcp_option_serializeex(dhcp_code_DHCP_Msg_Type, 1, &message->type, output);
-
- /*== Client Identifier (option 61) ==> RFC 2132 - 9.14. Client-identifier
- Code Len Type Client-Identifier
- +-----+-----+-----+-----+-----+---
- | 61 | n | t1 | i1 | i2 | ...
- +-----+-----+-----+-----+-----+---
- */
- if (message->hlen){
- uint8_t client_id[17]; // 16 /*sizeof(chaddr)*/+ 1/*htype*/
- /*if(client_id)*/{
- client_id[0] = message->htype;
- memcpy(&client_id[1], message->chaddr, message->hlen);
- tnet_dhcp_option_serializeex(dhcp_code_Client_Id, (message->hlen + 1), client_id, output);
- }
- }
- /*== Host name(10) ==> RFC 2132 - 3.14. Host Name Option
- Code Len Host Name
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 12 | n | h1 | h2 | h3 | h4 | h5 | h6 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- */
- if (TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->hostname){
- tnet_dhcp_option_serializeex(dhcp_code_Hostname, (uint8_t)tsk_strlen(ctx->hostname), ctx->hostname, output);
- }
- /*== Vendor classId(60) ==> RFC 2132 - 9.13. Vendor class identifier
- Code Len Vendor class Identifier
- +-----+-----+-----+-----+---
- | 60 | n | i1 | i2 | ...
- +-----+-----+-----+-----+---
- */
- if (TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->vendor_id){
- tnet_dhcp_option_serializeex(dhcp_code_Class_Id, (uint8_t)tsk_strlen(ctx->vendor_id), ctx->vendor_id, output);
- }
-
- /*== RFC 2132 - 9.10. Maximum DHCP Message Size (57)
- Code Len Length
- +-----+-----+-----+-----+
- | 57 | 2 | l1 | l2 |
- +-----+-----+-----+-----+
- */
- if (TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->max_msg_size){
- _2bytes = tnet_ntohs(ctx->max_msg_size);
- tnet_dhcp_option_serializeex(dhcp_code_DHCP_Max_Msg_Size, 2, &_2bytes, output);
- }
-
- /*== DHCP Options
- */
- {
- tsk_list_item_t *item;
- tnet_dhcp_option_t* option;
- tsk_list_foreach(item, message->options)
- {
- option = (tnet_dhcp_option_t*)item->data;
- if (tnet_dhcp_option_serialize(option, output)){
- TSK_DEBUG_WARN("Failed to serialize DHCP OPTION (%u)", option->code);
- }
- }
- }
-
- /* RFC 2131 - 4.1 Constructing and sending DHCP messages
- The last option must always be the 'end' option.
- */
- _1byte = dhcp_code_End;
- tsk_buffer_append(output, &(_1byte), 1);
+ tsk_buffer_t* output = 0;
+ uint8_t _1byte;
+ uint16_t _2bytes;
+ uint32_t _4bytes;
+
+ /* Check message validity */
+ if (!message) {
+ goto bail;
+ }
+
+ output = tsk_buffer_create_null();
+
+ /*== OP HTYPE HLEN HOPS */
+ _4bytes = (((uint32_t)(message->op)) << 24) |
+ (((uint32_t)(message->htype)) << 16) |
+ (((uint16_t)(message->hlen)) << 8) | message->hops;
+ _4bytes = (uint32_t)tnet_ntohl(_4bytes);
+ tsk_buffer_append(output, &(_4bytes), 4);
+
+ /*== XID */
+ _4bytes = (uint32_t)tnet_ntohl(message->xid);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== SECS */
+ _2bytes = tnet_ntohs(message->secs);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /*== FLAGS */
+ _2bytes = tnet_ntohs(message->flags);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /*== CIADDR */
+ _4bytes = (uint32_t)tnet_ntohl(message->ciaddr);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== YIADDR */
+ _4bytes = (uint32_t)tnet_ntohl(message->yiaddr);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== SIADDR */
+ _4bytes = (uint32_t)tnet_ntohl(message->siaddr);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== GIADDR */
+ _4bytes = (uint32_t)tnet_ntohl(message->giaddr);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ /*== CHADDR */
+ tsk_buffer_append(output, message->chaddr, sizeof(message->chaddr));
+ /*== sname (unused) */
+ tsk_buffer_append(output, message->sname, sizeof(message->sname));
+ /*== file (unused) */
+ tsk_buffer_append(output, message->file, sizeof(message->file));
+ /*== Magic Cookie */
+ _4bytes = (uint32_t)tnet_ntohl(TNET_DHCP_MAGIC_COOKIE);
+ tsk_buffer_append(output, &(_4bytes), 4);
+
+ /*== Message Type (option 53)
+ */
+ tnet_dhcp_option_serializeex(dhcp_code_DHCP_Msg_Type, 1, &message->type, output);
+
+ /*== Client Identifier (option 61) ==> RFC 2132 - 9.14. Client-identifier
+ Code Len Type Client-Identifier
+ +-----+-----+-----+-----+-----+---
+ | 61 | n | t1 | i1 | i2 | ...
+ +-----+-----+-----+-----+-----+---
+ */
+ if (message->hlen) {
+ uint8_t client_id[17]; // 16 /*sizeof(chaddr)*/+ 1/*htype*/
+ /*if(client_id)*/{
+ client_id[0] = message->htype;
+ memcpy(&client_id[1], message->chaddr, message->hlen);
+ tnet_dhcp_option_serializeex(dhcp_code_Client_Id, (message->hlen + 1), client_id, output);
+ }
+ }
+ /*== Host name(10) ==> RFC 2132 - 3.14. Host Name Option
+ Code Len Host Name
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 12 | n | h1 | h2 | h3 | h4 | h5 | h6 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ if (TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->hostname) {
+ tnet_dhcp_option_serializeex(dhcp_code_Hostname, (uint8_t)tsk_strlen(ctx->hostname), ctx->hostname, output);
+ }
+ /*== Vendor classId(60) ==> RFC 2132 - 9.13. Vendor class identifier
+ Code Len Vendor class Identifier
+ +-----+-----+-----+-----+---
+ | 60 | n | i1 | i2 | ...
+ +-----+-----+-----+-----+---
+ */
+ if (TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->vendor_id) {
+ tnet_dhcp_option_serializeex(dhcp_code_Class_Id, (uint8_t)tsk_strlen(ctx->vendor_id), ctx->vendor_id, output);
+ }
+
+ /*== RFC 2132 - 9.10. Maximum DHCP Message Size (57)
+ Code Len Length
+ +-----+-----+-----+-----+
+ | 57 | 2 | l1 | l2 |
+ +-----+-----+-----+-----+
+ */
+ if (TNET_DHCP_MESSAGE_IS_REQUEST(message) && ctx->max_msg_size) {
+ _2bytes = tnet_ntohs(ctx->max_msg_size);
+ tnet_dhcp_option_serializeex(dhcp_code_DHCP_Max_Msg_Size, 2, &_2bytes, output);
+ }
+
+ /*== DHCP Options
+ */
+ {
+ tsk_list_item_t *item;
+ tnet_dhcp_option_t* option;
+ tsk_list_foreach(item, message->options) {
+ option = (tnet_dhcp_option_t*)item->data;
+ if (tnet_dhcp_option_serialize(option, output)) {
+ TSK_DEBUG_WARN("Failed to serialize DHCP OPTION (%u)", option->code);
+ }
+ }
+ }
+
+ /* RFC 2131 - 4.1 Constructing and sending DHCP messages
+ The last option must always be the 'end' option.
+ */
+ _1byte = dhcp_code_End;
+ tsk_buffer_append(output, &(_1byte), 1);
bail:
- return output;
+ return output;
}
tnet_dhcp_message_t* tnet_dhcp_message_deserialize(const struct tnet_dhcp_ctx_s *ctx, const uint8_t *data, tsk_size_t size)
{
- tnet_dhcp_message_t *message = 0;
- uint8_t *dataPtr, *dataEnd, *dataStart;
-
- if (!data || !size)
- {
- goto bail;
- }
-
- if (size < TNET_DHCP_MESSAGE_MIN_SIZE){
- TSK_DEBUG_ERROR("DHCP message too short.");
- goto bail;
- }
-
- if (!(message = tnet_dhcp_reply_create())){ /* If REQUEST OP will be overridedden */
- TSK_DEBUG_ERROR("Failed to create new DHCP message.");
- goto bail;
- }
-
- dataPtr = (uint8_t*)data;
- dataStart = dataPtr;
- dataEnd = (dataStart + size);
-
- /*== op (1)*/
- message->op = *(dataPtr++);
- /*== htype (1) */
- message->htype = *(dataPtr++);
- /*== hlen (1) */
- message->hlen = *(dataPtr++);
- /*== htype (1) */
- message->hops = *(dataPtr++);
- /*== xid (4) */
- message->xid = (uint32_t)tnet_htonl_2(dataPtr);
- dataPtr += 4;
- /*== secs (2) */
- message->secs = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
- /*== flags (2) */
- message->flags = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
- /*== ciaddr (4) */
- message->ciaddr = (uint32_t)tnet_htonl_2(dataPtr);
- dataPtr += 4;
- /*== yiaddr (4) */
- message->yiaddr = (uint32_t)tnet_htonl_2(dataPtr);
- dataPtr += 4;
- /*== siaddr (4) */
- message->siaddr = (uint32_t)tnet_htonl_2(dataPtr);
- dataPtr += 4;
- /*== giaddr (4) */
- message->giaddr = (uint32_t)tnet_htonl_2(dataPtr);
- dataPtr += 4;
- /*== chaddr (16[max]) */
- memcpy(message->chaddr, dataPtr, message->hlen > 16 ? 16 : message->hlen);
- dataPtr += 16;
- /*== sname (64) */
- memcpy(message->sname, dataPtr, 64);
- dataPtr += 64;
- /*== file (128) */
- memcpy(message->file, dataPtr, 128);
- dataPtr += 128;
- /*== Magic Cookie (4) */
- if (tnet_htonl_2(dataPtr) != TNET_DHCP_MAGIC_COOKIE){
- TSK_DEBUG_ERROR("Invalid DHCP magic cookie.");
- // Do not exit ==> continue parsing.
- }
- dataPtr += 4;
-
- /*== options (variable) */
- while (dataPtr < dataEnd && *dataPtr != dhcp_code_End)
- {
- tnet_dhcp_option_t* option = tnet_dhcp_option_deserialize(dataPtr, (tsk_size_t)(dataEnd - dataPtr));
- if (option && option->value){
-
- if (option->code == dhcp_code_DHCP_Msg_Type){
- message->type = (tnet_dhcp_message_type_t)*TSK_BUFFER_TO_U8(option->value);
- }
-
- dataPtr += option->value->size + 2/*Code Len*/;
- tsk_list_push_back_data(message->options, (void**)&option);
- }
- else break;
- }
+ tnet_dhcp_message_t *message = 0;
+ uint8_t *dataPtr, *dataEnd, *dataStart;
+
+ if (!data || !size) {
+ goto bail;
+ }
+
+ if (size < TNET_DHCP_MESSAGE_MIN_SIZE) {
+ TSK_DEBUG_ERROR("DHCP message too short.");
+ goto bail;
+ }
+
+ if (!(message = tnet_dhcp_reply_create())) { /* If REQUEST OP will be overridedden */
+ TSK_DEBUG_ERROR("Failed to create new DHCP message.");
+ goto bail;
+ }
+
+ dataPtr = (uint8_t*)data;
+ dataStart = dataPtr;
+ dataEnd = (dataStart + size);
+
+ /*== op (1)*/
+ message->op = *(dataPtr++);
+ /*== htype (1) */
+ message->htype = *(dataPtr++);
+ /*== hlen (1) */
+ message->hlen = *(dataPtr++);
+ /*== htype (1) */
+ message->hops = *(dataPtr++);
+ /*== xid (4) */
+ message->xid = (uint32_t)tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== secs (2) */
+ message->secs = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+ /*== flags (2) */
+ message->flags = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+ /*== ciaddr (4) */
+ message->ciaddr = (uint32_t)tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== yiaddr (4) */
+ message->yiaddr = (uint32_t)tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== siaddr (4) */
+ message->siaddr = (uint32_t)tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== giaddr (4) */
+ message->giaddr = (uint32_t)tnet_htonl_2(dataPtr);
+ dataPtr += 4;
+ /*== chaddr (16[max]) */
+ memcpy(message->chaddr, dataPtr, message->hlen > 16 ? 16 : message->hlen);
+ dataPtr += 16;
+ /*== sname (64) */
+ memcpy(message->sname, dataPtr, 64);
+ dataPtr += 64;
+ /*== file (128) */
+ memcpy(message->file, dataPtr, 128);
+ dataPtr += 128;
+ /*== Magic Cookie (4) */
+ if (tnet_htonl_2(dataPtr) != TNET_DHCP_MAGIC_COOKIE) {
+ TSK_DEBUG_ERROR("Invalid DHCP magic cookie.");
+ // Do not exit ==> continue parsing.
+ }
+ dataPtr += 4;
+
+ /*== options (variable) */
+ while (dataPtr < dataEnd && *dataPtr != dhcp_code_End) {
+ tnet_dhcp_option_t* option = tnet_dhcp_option_deserialize(dataPtr, (tsk_size_t)(dataEnd - dataPtr));
+ if (option && option->value) {
+
+ if (option->code == dhcp_code_DHCP_Msg_Type) {
+ message->type = (tnet_dhcp_message_type_t)*TSK_BUFFER_TO_U8(option->value);
+ }
+
+ dataPtr += option->value->size + 2/*Code Len*/;
+ tsk_list_push_back_data(message->options, (void**)&option);
+ }
+ else {
+ break;
+ }
+ }
bail:
- return message;
+ return message;
}
const tnet_dhcp_option_t* tnet_dhcp_message_find_option(const tnet_dhcp_message_t *message, tnet_dhcp_option_code_t code)
{
- tsk_list_item_t *item;
+ tsk_list_item_t *item;
- if (!message){
- goto bail;
- }
+ if (!message) {
+ goto bail;
+ }
- tsk_list_foreach(item, message->options)
- {
- if (((tnet_dhcp_option_t*)item->data)->code == code){
- return ((tnet_dhcp_option_t*)item->data);
- }
- }
+ tsk_list_foreach(item, message->options) {
+ if (((tnet_dhcp_option_t*)item->data)->code == code) {
+ return ((tnet_dhcp_option_t*)item->data);
+ }
+ }
bail:
- return 0;
+ return 0;
}
int tnet_dhcp_message_add_codes(tnet_dhcp_message_t *self, tnet_dhcp_option_code_t codes[], unsigned codes_count)
{
- int ret = -1;
-
- if (!self){
- goto bail;
- }
- if (codes_count){
- unsigned i;
-
- tnet_dhcp_option_paramslist_t* option = (tnet_dhcp_option_paramslist_t*)tnet_dhcp_message_find_option(self, dhcp_code_Parameter_List);
- if (!option){
- tnet_dhcp_option_paramslist_t *option_paramslist = tnet_dhcp_option_paramslist_create();
- option = option_paramslist;
- tsk_list_push_back_data(self->options, (void**)&option_paramslist);
- }
-
- for (i = 0; i < codes_count; i++){
- if ((ret = tnet_dhcp_option_paramslist_add_code(option, codes[i]))){
- break;
- }
- }
- }
+ int ret = -1;
+
+ if (!self) {
+ goto bail;
+ }
+ if (codes_count) {
+ unsigned i;
+
+ tnet_dhcp_option_paramslist_t* option = (tnet_dhcp_option_paramslist_t*)tnet_dhcp_message_find_option(self, dhcp_code_Parameter_List);
+ if (!option) {
+ tnet_dhcp_option_paramslist_t *option_paramslist = tnet_dhcp_option_paramslist_create();
+ option = option_paramslist;
+ tsk_list_push_back_data(self->options, (void**)&option_paramslist);
+ }
+
+ for (i = 0; i < codes_count; i++) {
+ if ((ret = tnet_dhcp_option_paramslist_add_code(option, codes[i]))) {
+ break;
+ }
+ }
+ }
bail:
- return ret;
+ return ret;
}
@@ -315,35 +313,34 @@ bail:
//
static tsk_object_t* tnet_dhcp_message_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp_message_t *message = self;
- if (message){
- static uint32_t __dhcpmessage_unique_xid = 0;//(uint32_t)tsk_time_epoch();
-
- message->op = va_arg(*app, tnet_dhcp_message_op_t);
- message->htype = tnet_htype_Ethernet_10Mb;
- message->hlen = 0x06;
-
- message->xid = ++(__dhcpmessage_unique_xid);
- message->options = tsk_list_create();
- }
- return self;
+ tnet_dhcp_message_t *message = self;
+ if (message) {
+ static uint32_t __dhcpmessage_unique_xid = 0;//(uint32_t)tsk_time_epoch();
+
+ message->op = va_arg(*app, tnet_dhcp_message_op_t);
+ message->htype = tnet_htype_Ethernet_10Mb;
+ message->hlen = 0x06;
+
+ message->xid = ++(__dhcpmessage_unique_xid);
+ message->options = tsk_list_create();
+ }
+ return self;
}
static tsk_object_t* tnet_dhcp_message_dtor(tsk_object_t * self)
{
- tnet_dhcp_message_t *message = self;
- if (message){
- TSK_OBJECT_SAFE_FREE(message->options);
- }
- return self;
+ tnet_dhcp_message_t *message = self;
+ if (message) {
+ TSK_OBJECT_SAFE_FREE(message->options);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp_message_def_s =
-{
- sizeof(tnet_dhcp_message_t),
- tnet_dhcp_message_ctor,
- tnet_dhcp_message_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp_message_def_s = {
+ sizeof(tnet_dhcp_message_t),
+ tnet_dhcp_message_ctor,
+ tnet_dhcp_message_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp_message_def_t = &tnet_dhcp_message_def_s;
diff --git a/tinyNET/src/dhcp/tnet_dhcp_message.h b/tinyNET/src/dhcp/tnet_dhcp_message.h
index c7005fa..53ead75 100755
--- a/tinyNET/src/dhcp/tnet_dhcp_message.h
+++ b/tinyNET/src/dhcp/tnet_dhcp_message.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -50,158 +50,155 @@ struct tnet_dhcp_ctx_s;
/** List of all supported DHCP message (see RFC 2131).
*/
-typedef enum tnet_dhcp_message_type_e
-{
- /**< DHCPDISCOVER - Client broadcast to locate available servers.
- */
- dhcp_type_discover = 1,
-
- /**< DHCPOFFER - Server to client in response to DHCPDISCOVER with
- offer of configuration parameters.
- */
- dhcp_type_offer = 2,
-
- /**< DHCPREQUEST - Client message to servers either (a) requesting
- offered parameters from one server and implicitly
- declining offers from all others, (b) confirming
- correctness of previously allocated address after,
- e.g., system reboot, or (c) extending the lease on a
- particular network address.
- */
- dhcp_type_request = 3,
-
- /**< DHCPDECLINE - Client to server indicating network address is already
+typedef enum tnet_dhcp_message_type_e {
+ /**< DHCPDISCOVER - Client broadcast to locate available servers.
+ */
+ dhcp_type_discover = 1,
+
+ /**< DHCPOFFER - Server to client in response to DHCPDISCOVER with
+ offer of configuration parameters.
+ */
+ dhcp_type_offer = 2,
+
+ /**< DHCPREQUEST - Client message to servers either (a) requesting
+ offered parameters from one server and implicitly
+ declining offers from all others, (b) confirming
+ correctness of previously allocated address after,
+ e.g., system reboot, or (c) extending the lease on a
+ particular network address.
+ */
+ dhcp_type_request = 3,
+
+ /**< DHCPDECLINE - Client to server indicating network address is already
in use.
- */
- dhcp_type_decline = 4,
-
- /**< DHCPACK - Server to client with configuration parameters,
- including committed network address.
- */
- dhcp_type_ack = 5,
-
- /**< DHCPNAK - Server to client indicating client's notion of network
- address is incorrect (e.g., client has moved to new
- subnet) or client's lease as expired
- */
- dhcp_type_nack = 6,
-
- /**< DHCPRELEASE - Client to server relinquishing network address and
- cancelling remaining lease.
- */
- dhcp_type_release = 7,
-
- /**< DHCPINFORM - Client to server, asking only for local configuration
- parameters; client already has externally configured
- network address.
- */
- dhcp_type_inform = 8,
+ */
+ dhcp_type_decline = 4,
+
+ /**< DHCPACK - Server to client with configuration parameters,
+ including committed network address.
+ */
+ dhcp_type_ack = 5,
+
+ /**< DHCPNAK - Server to client indicating client's notion of network
+ address is incorrect (e.g., client has moved to new
+ subnet) or client's lease as expired
+ */
+ dhcp_type_nack = 6,
+
+ /**< DHCPRELEASE - Client to server relinquishing network address and
+ cancelling remaining lease.
+ */
+ dhcp_type_release = 7,
+
+ /**< DHCPINFORM - Client to server, asking only for local configuration
+ parameters; client already has externally configured
+ network address.
+ */
+ dhcp_type_inform = 8,
}
tnet_dhcp_message_type_t;
/** DHCP message OP code / message type.
*/
-typedef enum tnet_dhcp_message_op_e
-{
- dhcp_op_bootrequest = 1,
- dhcp_op_bootreply = 2
+typedef enum tnet_dhcp_message_op_e {
+ dhcp_op_bootrequest = 1,
+ dhcp_op_bootreply = 2
}
tnet_dhcp_message_op_t;
/** BOOTP/DHCP message as per RFC 2131 subclause 2.
*/
-typedef struct tnet_dhcp_message_s
-{
- TSK_DECLARE_OBJECT;
-
- /**< DHCP message type. Mandatory.
- */
- tnet_dhcp_message_type_t type;
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | op (1) | htype (1) | hlen (1) | hops (1) |
- +---------------+---------------+---------------+---------------+
- | xid (4) |
- +-------------------------------+-------------------------------+
- | secs (2) | flags (2) |
- +-------------------------------+-------------------------------+
- | ciaddr (4) |
- +---------------------------------------------------------------+
- | yiaddr (4) |
- +---------------------------------------------------------------+
- | siaddr (4) |
- +---------------------------------------------------------------+
- | giaddr (4) |
- +---------------------------------------------------------------+
- | |
- | chaddr (16) |
- | |
- | |
- +---------------------------------------------------------------+
- | |
- | sname (64) |
- +---------------------------------------------------------------+
- | |
- | file (128) |
- +---------------------------------------------------------------+
- | |
- | options (variable) |
- +---------------------------------------------------------------+
- */
-
- /**< Message op code / message type (1-byte).
+typedef struct tnet_dhcp_message_s {
+ TSK_DECLARE_OBJECT;
+
+ /**< DHCP message type. Mandatory.
+ */
+ tnet_dhcp_message_type_t type;
+ /*
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | op (1) | htype (1) | hlen (1) | hops (1) |
+ +---------------+---------------+---------------+---------------+
+ | xid (4) |
+ +-------------------------------+-------------------------------+
+ | secs (2) | flags (2) |
+ +-------------------------------+-------------------------------+
+ | ciaddr (4) |
+ +---------------------------------------------------------------+
+ | yiaddr (4) |
+ +---------------------------------------------------------------+
+ | siaddr (4) |
+ +---------------------------------------------------------------+
+ | giaddr (4) |
+ +---------------------------------------------------------------+
+ | |
+ | chaddr (16) |
+ | |
+ | |
+ +---------------------------------------------------------------+
+ | |
+ | sname (64) |
+ +---------------------------------------------------------------+
+ | |
+ | file (128) |
+ +---------------------------------------------------------------+
+ | |
+ | options (variable) |
+ +---------------------------------------------------------------+
+ */
+
+ /**< Message op code / message type (1-byte).
1 = BOOTREQUEST, 2 = BOOTREPLY
- */
- tnet_dhcp_message_op_t op;
- /**< Hardware address type, see ARP section in "Assigned Numbers" RFC; e.g., '1' = 10mb ethernet.
- For more information see RFC 1340.
- */
+ */
+ tnet_dhcp_message_op_t op;
+ /**< Hardware address type, see ARP section in "Assigned Numbers" RFC; e.g., '1' = 10mb ethernet.
+ For more information see RFC 1340.
+ */
tnet_hardware_type_t htype;
- /**< Hardware address length (e.g. '6' for 10mb ethernet). tsk_strlen(chaddr).
- */
+ /**< Hardware address length (e.g. '6' for 10mb ethernet). tsk_strlen(chaddr).
+ */
uint8_t hlen;
- /**< Client sets to zero, optionally used by relay agents when booting via a relay agent.
- */
+ /**< Client sets to zero, optionally used by relay agents when booting via a relay agent.
+ */
uint8_t hops;
- /**< Transaction ID, a random number chosen by the client, used by the client
- and server to associate messages and responses between a client and a server.
- */
+ /**< Transaction ID, a random number chosen by the client, used by the client
+ and server to associate messages and responses between a client and a server.
+ */
uint32_t xid;
- /**< Filled in by client, seconds elapsed since client began address acquisition or renewal process.
- */
+ /**< Filled in by client, seconds elapsed since client began address acquisition or renewal process.
+ */
uint16_t secs;
- /**< Flags (see figure 2)
- */
+ /**< Flags (see figure 2)
+ */
uint16_t flags;
- /**< Client IP address; only filled in if client is in BOUND, RENEW or REBINDING
- state and can respond to ARP requests.
- */
+ /**< Client IP address; only filled in if client is in BOUND, RENEW or REBINDING
+ state and can respond to ARP requests.
+ */
uint32_t ciaddr;
- /**< 'your' (client) IP address.
- */
+ /**< 'your' (client) IP address.
+ */
uint32_t yiaddr;
- /**< IP address of next server to use in bootstrap;
- returned in DHCPOFFER, DHCPACK by server.
- */
+ /**< IP address of next server to use in bootstrap;
+ returned in DHCPOFFER, DHCPACK by server.
+ */
uint32_t siaddr;
- /**< Relay agent IP address, used in booting via a relay agent.
- */
+ /**< Relay agent IP address, used in booting via a relay agent.
+ */
uint32_t giaddr;
- /**< Client hardware address.
- */
+ /**< Client hardware address.
+ */
uint8_t chaddr[16];
- /**< Optional server host name, null terminated string.
- */
+ /**< Optional server host name, null terminated string.
+ */
uint8_t sname[64];
- /**<Boot file name, null terminated string; "generic" name or null in DHCPDISCOVER,
- fully qualifieddirectory-path name in DHCPOFFER.
- */
+ /**<Boot file name, null terminated string; "generic" name or null in DHCPDISCOVER,
+ fully qualifieddirectory-path name in DHCPOFFER.
+ */
uint8_t file[128];
- /**Optional parameters field. See the options documents for a list of defined options.
- For more information please refer to RFC 2132, 1497 and 1533.
- */
+ /**Optional parameters field. See the options documents for a list of defined options.
+ For more information please refer to RFC 2132, 1497 and 1533.
+ */
tnet_dhcp_options_L_t *options;
}
tnet_dhcp_message_t;
diff --git a/tinyNET/src/dhcp/tnet_dhcp_option.c b/tinyNET/src/dhcp/tnet_dhcp_option.c
index 3679a62..037d65a 100755
--- a/tinyNET/src/dhcp/tnet_dhcp_option.c
+++ b/tinyNET/src/dhcp/tnet_dhcp_option.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,140 +38,132 @@
tnet_dhcp_option_t* tnet_dhcp_option_create(tnet_dhcp_option_code_t code)
{
- return tsk_object_new(tnet_dhcp_option_def_t, code);
+ return tsk_object_new(tnet_dhcp_option_def_t, code);
}
tnet_dhcp_option_paramslist_t* tnet_dhcp_option_paramslist_create()
{
- return tsk_object_new(tnet_dhcp_option_paramslist_def_t);
+ return tsk_object_new(tnet_dhcp_option_paramslist_def_t);
}
tnet_dhcp_option_dns_t* tnet_dhcp_option_dns_create(const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp_option_dns_def_t, payload, payload_size);
+ return tsk_object_new(tnet_dhcp_option_dns_def_t, payload, payload_size);
}
-/** Initializes DHCPv4 option.
+/** Initializes DHCPv4 option.
*
- * @param [in,out] self The option to initialize.
- * @param code The code of the option to initialize.
+ * @param [in,out] self The option to initialize.
+ * @param code The code of the option to initialize.
*
* @return Zero if succeed and non-zero error code otherwise.
**/
int tnet_dhcp_option_init(tnet_dhcp_option_t *self, tnet_dhcp_option_code_t code)
{
- if(self)
- {
- if(!self->initialized)
- {
- self->code = code;
- //option->value = tsk_buffer_create_null();
-
- self->initialized = tsk_true;
- return 0;
- }
- return -2;
- }
- return -1;
+ if(self) {
+ if(!self->initialized) {
+ self->code = code;
+ //option->value = tsk_buffer_create_null();
+
+ self->initialized = tsk_true;
+ return 0;
+ }
+ return -2;
+ }
+ return -1;
}
int tnet_dhcp_option_deinit(tnet_dhcp_option_t *self)
{
- if(self)
- {
- if(self->initialized)
- {
- TSK_OBJECT_SAFE_FREE(self->value);
-
- self->initialized = tsk_false;
- return 0;
- }
- return -2;
- }
- return -1;
+ if(self) {
+ if(self->initialized) {
+ TSK_OBJECT_SAFE_FREE(self->value);
+
+ self->initialized = tsk_false;
+ return 0;
+ }
+ return -2;
+ }
+ return -1;
}
tnet_dhcp_option_t* tnet_dhcp_option_deserialize(const void* data, tsk_size_t size)
{
- tnet_dhcp_option_t *option = 0;
- uint8_t* dataPtr = ((uint8_t*)data);
- //uint8_t* dataEnd = (dataPtr+size);
-
- tnet_dhcp_option_code_t code;
- uint8_t len;
-
- /* Check validity */
- if(!dataPtr || size<2/*Code Len*/){
- goto bail;
- }
-
- code = (tnet_dhcp_option_code_t)*dataPtr++;
- len = *dataPtr++;
-
- switch(code)
- {
- case dhcp_code_SIP_Servers_DHCP_Option:
- {
- option = (tnet_dhcp_option_t *)tnet_dhcp_option_sip_create(dataPtr, len);
- break;
- }
-
- case dhcp_code_Domain_Server:
- {
- option = (tnet_dhcp_option_t *)tnet_dhcp_option_dns_create(dataPtr, len);
- break;
- }
-
- default:
- {
- option = tnet_dhcp_option_create(code);
- }
- }
-
- /* In all case */
- if(option && !option->value && len){
- option->value = tsk_buffer_create((((uint8_t*)data) + 2/*Code Len*/), len);
- }
+ tnet_dhcp_option_t *option = 0;
+ uint8_t* dataPtr = ((uint8_t*)data);
+ //uint8_t* dataEnd = (dataPtr+size);
+
+ tnet_dhcp_option_code_t code;
+ uint8_t len;
+
+ /* Check validity */
+ if(!dataPtr || size<2/*Code Len*/) {
+ goto bail;
+ }
+
+ code = (tnet_dhcp_option_code_t)*dataPtr++;
+ len = *dataPtr++;
+
+ switch(code) {
+ case dhcp_code_SIP_Servers_DHCP_Option: {
+ option = (tnet_dhcp_option_t *)tnet_dhcp_option_sip_create(dataPtr, len);
+ break;
+ }
+
+ case dhcp_code_Domain_Server: {
+ option = (tnet_dhcp_option_t *)tnet_dhcp_option_dns_create(dataPtr, len);
+ break;
+ }
+
+ default: {
+ option = tnet_dhcp_option_create(code);
+ }
+ }
+
+ /* In all case */
+ if(option && !option->value && len) {
+ option->value = tsk_buffer_create((((uint8_t*)data) + 2/*Code Len*/), len);
+ }
bail:
- return option;
+ return option;
}
int tnet_dhcp_option_serialize(const tnet_dhcp_option_t* self, tsk_buffer_t *output)
{
- if(!self || !output){
- return -1;
- }
-
- /* Code */
- tsk_buffer_append(output, &(self->code), 1);
-
- if(self->value){
- /* Length */
- tsk_buffer_append(output, &(self->value->size), 1);
-
- /* Value */
- tsk_buffer_append(output, self->value->data, self->value->size);
- }
- else{
- /* Length */
- static uint8_t zero = 0x00;
- tsk_buffer_append(output, &zero, 1);
- }
-
- return 0;
+ if(!self || !output) {
+ return -1;
+ }
+
+ /* Code */
+ tsk_buffer_append(output, &(self->code), 1);
+
+ if(self->value) {
+ /* Length */
+ tsk_buffer_append(output, &(self->value->size), 1);
+
+ /* Value */
+ tsk_buffer_append(output, self->value->data, self->value->size);
+ }
+ else {
+ /* Length */
+ static uint8_t zero = 0x00;
+ tsk_buffer_append(output, &zero, 1);
+ }
+
+ return 0;
}
int tnet_dhcp_option_serializeex(tnet_dhcp_option_code_t code, uint8_t length, const void* value, tsk_buffer_t *output)
{
- if(value && length && output){
- tsk_buffer_append(output, &(code), 1);
- tsk_buffer_append(output, &(length), 1);
- tsk_buffer_append(output, value, length);
-
- return 0;
- }
- return -1;
+ if(value && length && output) {
+ tsk_buffer_append(output, &(code), 1);
+ tsk_buffer_append(output, &(length), 1);
+ tsk_buffer_append(output, value, length);
+
+ return 0;
+ }
+ return -1;
}
//
@@ -179,28 +171,27 @@ int tnet_dhcp_option_serializeex(tnet_dhcp_option_code_t code, uint8_t length, c
//
static tsk_object_t* tnet_dhcp_option_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp_option_t *option = self;
- if(option){
- tnet_dhcp_option_init(option, va_arg(*app, tnet_dhcp_option_code_t));
- }
- return self;
+ tnet_dhcp_option_t *option = self;
+ if(option) {
+ tnet_dhcp_option_init(option, va_arg(*app, tnet_dhcp_option_code_t));
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp_option_dtor(tsk_object_t * self)
-{
- tnet_dhcp_option_t *option = self;
- if(option){
- tnet_dhcp_option_deinit(option);
- }
- return self;
+static tsk_object_t* tnet_dhcp_option_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_option_t *option = self;
+ if(option) {
+ tnet_dhcp_option_deinit(option);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp_option_def_s =
-{
- sizeof(tnet_dhcp_option_t),
- tnet_dhcp_option_ctor,
- tnet_dhcp_option_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp_option_def_s = {
+ sizeof(tnet_dhcp_option_t),
+ tnet_dhcp_option_ctor,
+ tnet_dhcp_option_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp_option_def_t = &tnet_dhcp_option_def_s;
@@ -211,13 +202,13 @@ const tsk_object_def_t *tnet_dhcp_option_def_t = &tnet_dhcp_option_def_s;
*=======================================================================================*/
int tnet_dhcp_option_paramslist_add_code(tnet_dhcp_option_paramslist_t* self, tnet_dhcp_option_code_t code)
{
- if(self){
- if(!TNET_DHCP_OPTION(self)->value){
- TNET_DHCP_OPTION(self)->value = tsk_buffer_create_null();
- }
- return tsk_buffer_append(TNET_DHCP_OPTION(self)->value, &code, 1);
- }
- return -1;
+ if(self) {
+ if(!TNET_DHCP_OPTION(self)->value) {
+ TNET_DHCP_OPTION(self)->value = tsk_buffer_create_null();
+ }
+ return tsk_buffer_append(TNET_DHCP_OPTION(self)->value, &code, 1);
+ }
+ return -1;
}
//
@@ -225,30 +216,29 @@ int tnet_dhcp_option_paramslist_add_code(tnet_dhcp_option_paramslist_t* self, tn
//
static tsk_object_t* tnet_dhcp_option_paramslist_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp_option_paramslist_t *option = self;
- if(option){
- /* init base */
- tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_Parameter_List);
- }
- return self;
+ tnet_dhcp_option_paramslist_t *option = self;
+ if(option) {
+ /* init base */
+ tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_Parameter_List);
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp_option_paramslist_dtor(tsk_object_t * self)
-{
- tnet_dhcp_option_paramslist_t *option = self;
- if(option){
- /* deinit base */
- tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
- }
- return self;
+static tsk_object_t* tnet_dhcp_option_paramslist_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_option_paramslist_t *option = self;
+ if(option) {
+ /* deinit base */
+ tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp_option_paramslist_def_s =
-{
- sizeof(tnet_dhcp_option_paramslist_t),
- tnet_dhcp_option_paramslist_ctor,
- tnet_dhcp_option_paramslist_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp_option_paramslist_def_s = {
+ sizeof(tnet_dhcp_option_paramslist_t),
+ tnet_dhcp_option_paramslist_ctor,
+ tnet_dhcp_option_paramslist_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp_option_paramslist_def_t = &tnet_dhcp_option_paramslist_def_s;
@@ -261,66 +251,65 @@ const tsk_object_def_t *tnet_dhcp_option_paramslist_def_t = &tnet_dhcp_option_pa
//
static tsk_object_t* tnet_dhcp_option_dns_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp_option_dns_t *option = self;
- if(option){
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- const uint8_t* payloadPtr = (const uint8_t*)payload;
- const uint8_t* payloadEnd = (payloadPtr + payload_size);
-
- /* init base */
- tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_Domain_Server);
-
- option->servers = tsk_list_create();
-
- if(payload_size<4 || payload_size%4){
- TSK_DEBUG_ERROR("DHCP - The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.");
- }
- else{
- tsk_size_t i;
- char* ip4 = 0;
- uint32_t address;
- tsk_string_t* addrstring;
-
- for(i=0; i<payload_size && (payloadPtr< payloadEnd); i+=4){
- /*
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- */
- address = (uint32_t)tnet_htonl_2(payloadPtr);
- tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
-
- addrstring = tsk_string_create(ip4);
- tsk_list_push_back_data(option->servers, (void*)&addrstring);
-
- TSK_FREE(ip4);
- payloadPtr+= 4;
- }
- }
- }
- return self;
+ tnet_dhcp_option_dns_t *option = self;
+ if(option) {
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ const uint8_t* payloadPtr = (const uint8_t*)payload;
+ const uint8_t* payloadEnd = (payloadPtr + payload_size);
+
+ /* init base */
+ tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_Domain_Server);
+
+ option->servers = tsk_list_create();
+
+ if(payload_size<4 || payload_size%4) {
+ TSK_DEBUG_ERROR("DHCP - The minimum length for this option is 4 octets, and the length MUST always be a multiple of 4.");
+ }
+ else {
+ tsk_size_t i;
+ char* ip4 = 0;
+ uint32_t address;
+ tsk_string_t* addrstring;
+
+ for(i=0; i<payload_size && (payloadPtr< payloadEnd); i+=4) {
+ /*
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ address = (uint32_t)tnet_htonl_2(payloadPtr);
+ tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
+
+ addrstring = tsk_string_create(ip4);
+ tsk_list_push_back_data(option->servers, (void*)&addrstring);
+
+ TSK_FREE(ip4);
+ payloadPtr+= 4;
+ }
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp_option_dns_dtor(tsk_object_t * self)
-{
- tnet_dhcp_option_dns_t *option = self;
- if(option){
- /* deinit base */
- tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
-
- TSK_OBJECT_SAFE_FREE(option->servers);
- }
- return self;
+static tsk_object_t* tnet_dhcp_option_dns_dtor(tsk_object_t * self)
+{
+ tnet_dhcp_option_dns_t *option = self;
+ if(option) {
+ /* deinit base */
+ tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
+
+ TSK_OBJECT_SAFE_FREE(option->servers);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp_option_dns_def_s =
-{
- sizeof(tnet_dhcp_option_dns_t),
- tnet_dhcp_option_dns_ctor,
- tnet_dhcp_option_dns_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp_option_dns_def_s = {
+ sizeof(tnet_dhcp_option_dns_t),
+ tnet_dhcp_option_dns_ctor,
+ tnet_dhcp_option_dns_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp_option_dns_def_t = &tnet_dhcp_option_dns_def_s;
diff --git a/tinyNET/src/dhcp/tnet_dhcp_option.h b/tinyNET/src/dhcp/tnet_dhcp_option.h
index 0d16ac1..db3ac16 100755
--- a/tinyNET/src/dhcp/tnet_dhcp_option.h
+++ b/tinyNET/src/dhcp/tnet_dhcp_option.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,191 +39,189 @@ TNET_BEGIN_DECLS
#define TNET_DHCP_OPTION(self) ((tnet_dhcp_option_t*)(self))
-typedef enum tnet_dhcp_option_code_e
-{
- dhcp_code_Pad= 0 ,/**< Pad 0 None [RFC2132] */
- dhcp_code_Subnet_Mask= 1 ,/**< Subnet Mask 4 Subnet Mask Value [RFC2132] */
- dhcp_code_Time_Offset= 2 ,/**< Time Offset 4 Time Offset in Seconds from UTC [RFC2132] (note: deprecated by 100 and 101) */
- dhcp_code_Router= 3 ,/**< Router N N/4 Router addresses [RFC2132] */
- dhcp_code_Time_Server= 4 ,/**< Time Server N N/4 Timeserver addresses [RFC2132] */
- dhcp_code_Name_Server= 5 ,/**< Name Server N N/4 IEN-116 Server addresses [RFC2132] */
- dhcp_code_Domain_Server= 6 ,/**< Domain Server N N/4 DNS Server addresses [RFC2132] */
- dhcp_code_Log_Server= 7 ,/**< Log Server N N/4 Logging Server addresses [RFC2132] */
- dhcp_code_Quotes_Server= 8 ,/**< Quotes Server N N/4 Quotes Server addresses [RFC2132] */
- dhcp_code_LPR_Server= 9 ,/**< LPR Server N N/4 Printer Server addresses [RFC2132] */
- dhcp_code_Impress_Server= 10 ,/**< Impress Server N N/4 Impress Server addresses [RFC2132] */
- dhcp_code_RLP_Server= 11 ,/**< RLP Server N N/4 RLP Server addresses [RFC2132] */
- dhcp_code_Hostname= 12 ,/**< Hostname N Hostname string [RFC2132] */
- dhcp_code_Boot_File_Size= 13 ,/**< Boot File Size 2 Size of boot file in 512 byte chunks [RFC2132] */
- dhcp_code_Merit_Dump_File= 14 ,/**< Merit Dump File N Client to dump and name the file to dump it to [RFC2132] */
- dhcp_code_Domain_Name= 15 ,/**< Domain Name N The DNS domain name of the client [RFC2132] */
- dhcp_code_Swap_Server= 16 ,/**< Swap Server N Swap Server address [RFC2132] */
- dhcp_code_Root_Path= 17 ,/**< Root Path N Path name for root disk [RFC2132] */
- dhcp_code_Extension_File= 18 ,/**< Extension File N Path name for more BOOTP info [RFC2132] */
- dhcp_code_Forward_On_Off= 19 ,/**< Forward On/Off 1 Enable/Disable IP Forwarding [RFC2132] */
- dhcp_code_SrcRte_On_Off = 20 ,/**< SrcRte On/Off 1 Enable/Disable Source Routing [RFC2132] */
- dhcp_code_Policy_Filter= 21 ,/**< Policy Filter N Routing Policy Filters [RFC2132] */
- dhcp_code_Max_DG_Assembly= 22 ,/**< Max DG Assembly 2 Max Datagram Reassembly Size [RFC2132] */
- dhcp_code_Default_IP_TTL= 23 ,/**< Default IP TTL 1 Default IP Time to Live [RFC2132] */
- dhcp_code_MTU_Timeout= 24 ,/**< MTU Timeout 4 Path MTU Aging Timeout [RFC2132] */
- dhcp_code_MTU_Plateau= 25 ,/**< MTU Plateau N Path MTU Plateau Table [RFC2132] */
- dhcp_code_MTU_Interface= 26 ,/**< MTU Interface 2 Interface MTU Size [RFC2132] */
- dhcp_code_MTU_Subnet= 27 ,/**< MTU Subnet 1 All Subnets are Local [RFC2132] */
- dhcp_code_Broadcast_Address= 28 ,/**< Broadcast Address 4 Broadcast Address [RFC2132] */
- dhcp_code_Mask_Discovery= 29 ,/**< Mask Discovery 1 Perform Mask Discovery [RFC2132] */
- dhcp_code_Mask_Supplier= 30 ,/**< Mask Supplier 1 Provide Mask to Others [RFC2132] */
- dhcp_code_Router_Discovery= 31 ,/**< Router Discovery 1 Perform Router Discovery [RFC2132] */
- dhcp_code_Router_Request= 32 ,/**< Router Request 4 Router Solicitation Address [RFC2132] */
- dhcp_code_Static_Route= 33 ,/**< Static Route N Static Routing Table [RFC2132] */
- dhcp_code_Trailers= 34 ,/**< Trailers 1 Trailer Encapsulation [RFC2132] */
- dhcp_code_ARP_Timeout= 35 ,/**< ARP Timeout 4 ARP Cache Timeout [RFC2132] */
- dhcp_code_Ethernet= 36 ,/**< Ethernet 1 Ethernet Encapsulation [RFC2132] */
- dhcp_code_Default_TCP_TTL= 37 ,/**< Default TCP TTL 1 Default TCP Time to Live [RFC2132] */
- dhcp_code_Keepalive_Time= 38 ,/**< Keepalive Time 4 TCP Keepalive Interval [RFC2132] */
- dhcp_code_Keepalive_Data= 39 ,/**< Keepalive Data 1 TCP Keepalive Garbage [RFC2132] */
- dhcp_code_NIS_Domain= 40 ,/**< NIS Domain N NIS Domain Name [RFC2132] */
- dhcp_code_NIS_Servers= 41 ,/**< NIS Servers N NIS Server Addresses [RFC2132] */
- dhcp_code_NTP_Servers= 42 ,/**< NTP Servers N NTP Server Addresses [RFC2132] */
- dhcp_code_Vendor_Specific= 43 ,/**< Vendor Specific N Vendor Specific Information [RFC2132] */
- dhcp_code_NETBIOS_Name_Srv= 44 ,/**< NETBIOS Name Srv N NETBIOS Name Servers [RFC2132] */
- dhcp_code_NETBIOS_Dist_Srv= 45 ,/**< NETBIOS Dist Srv N NETBIOS Datagram Distribution [RFC2132] */
- dhcp_code_NETBIOS_Node_Type= 46 ,/**< NETBIOS Node Type 1 NETBIOS Node Type [RFC2132] */
- dhcp_code_NETBIOS_Scope= 47 ,/**< NETBIOS Scope N NETBIOS Scope [RFC2132] */
- dhcp_code_X_Window_Font= 48 ,/**< X Window Font N X Window Font Server [RFC2132] */
- dhcp_code_X_Window_Manager= 49 ,/**< X Window Manager N X Window Display Manager [RFC2132] */
- dhcp_code_Address_Request= 50 ,/**< Address Request 4 Requested IP Address [RFC2132] */
- dhcp_code_Address_Time= 51 ,/**< Address Time 4 IP Address Lease Time [RFC2132] */
- dhcp_code_Overload= 52 ,/**< Overload 1 Overload "sname" or "file" [RFC2132] */
- dhcp_code_DHCP_Msg_Type= 53 ,/**< DHCP Msg Type 1 DHCP Message Type [RFC2132] */
- dhcp_code_DHCP_Server_Id= 54 ,/**< DHCP Server Id 4 DHCP Server Identification [RFC2132] */
- dhcp_code_Parameter_List= 55 ,/**< Parameter List N Parameter Request List [RFC2132] */
- dhcp_code_DHCP_Error_Message= 56 ,/**< DHCP Message N DHCP Error Message [RFC2132] */
- dhcp_code_DHCP_Max_Msg_Size= 57 ,/**< DHCP Max Msg Size 2 DHCP Maximum Message Size [RFC2132] */
- dhcp_code_Renewal_Time= 58 ,/**< Renewal Time 4 DHCP Renewal (T1) Time [RFC2132] */
- dhcp_code_Rebinding_Time= 59 ,/**< Rebinding Time 4 DHCP Rebinding (T2) Time [RFC2132] */
- dhcp_code_Class_Id= 60 ,/**< Class Id N Class Identifier [RFC2132] */
- dhcp_code_Client_Id= 61 ,/**< Client Id N Client Identifier [RFC2132] */
- dhcp_code_NetWare_IP_Domain= 62 ,/**< NetWare/IP Domain N NetWare/IP Domain Name [RFC2242] */
- dhcp_code_NetWare_IP_Option= 63 ,/**< NetWare/IP Option N NetWare/IP sub Options [RFC2242] */
- dhcp_code_NIS_Domain_Name= 64 ,/**< NIS-Domain-Name N NIS+ v3 Client Domain Name [RFC2132] */
- dhcp_code_NIS_Server_Addr = 65 ,/**< NIS-Server-Addr N NIS+ v3 Server Addresses [RFC2132] */
- dhcp_code_Server_Name= 66 ,/**< Server-Name N TFTP Server Name [RFC2132] */
- dhcp_code_Bootfile_Name= 67 ,/**< Bootfile-Name N Boot File Name [RFC2132] */
- dhcp_code_Home_Agent_Addrs= 68 ,/**< Home-Agent-Addrs N Home Agent Addresses [RFC2132] */
- dhcp_code_SMTP_Server= 69 ,/**< SMTP-Server N Simple Mail Server Addresses [RFC2132] */
- dhcp_code_POP3_Server= 70 ,/**< POP3-Server N Post Office Server Addresses [RFC2132] */
- dhcp_code_NNTP_Server= 71 ,/**< NNTP-Server N Network News Server Addresses [RFC2132] */
- dhcp_code_WWW_Server= 72 ,/**< WWW-Server N WWW Server Addresses [RFC2132] */
- dhcp_code_Finger_Server= 73 ,/**< Finger-Server N Finger Server Addresses [RFC2132] */
- dhcp_code_IRC_Server= 74 ,/**< IRC-Server N Chat Server Addresses [RFC2132] */
- dhcp_code_StreetTalk_Server= 75 ,/**< StreetTalk-Server N StreetTalk Server Addresses [RFC2132] */
- dhcp_code_STDA_Server= 76 ,/**< STDA-Server N ST Directory Assist. Addresses [RFC2132] */
- dhcp_code_User_Class= 77 ,/**< User-Class N User Class Information [RFC3004] */
- dhcp_code_Directory_Agent = 78 ,/**< Directory Agent N directory agent information [RFC2610] */
- dhcp_code_Service_Scope = 79 ,/**< Service Scope N service location agent scope [RFC2610] */
- dhcp_code_Rapid_Commit= 80 ,/**< Rapid Commit 0 Rapid Commit [RFC4039] */
- dhcp_code_Client_FQDN = 81 ,/**< Client FQDN N Fully Qualified Domain Name [RFC4702] */
- dhcp_code_Relay_Agent_Information= 82 ,/**< Relay Agent Information N Relay Agent Information [RFC3046] */
- dhcp_code_iSNS= 83 ,/**< iSNS N Internet Storage Name Service [RFC4174] */
- //84 REMOVED/Unassigned [RFC3679] */
- dhcp_code_NDS_Servers= 85 ,/**< NDS Servers N Novell Directory Services [RFC2241] */
- dhcp_code_NDS_Tree_Name= 86 ,/**< NDS Tree Name N Novell Directory Services [RFC2241] */
- dhcp_code_NDS_Context= 87 ,/**< NDS Context N Novell Directory Services [RFC2241] */
- dhcp_code_BCMCS_Controller_Domain_Name_list= 88 ,/**< BCMCS Controller Domain Name list [RFC4280] */
- dhcp_code_BCMCS_Controller_IPv4_address_option= 89 ,/**< BCMCS Controller IPv4 address option [RFC4280] */
- dhcp_code_Authentication= 90 ,/**< Authentication N Authentication [RFC3118] */
- dhcp_code_client_last_transaction_time= 91 ,/**< client-last-transaction-time option [RFC4388] */
- dhcp_code_associated_ip= 92 ,/**< associated-ip option [RFC4388] */
- dhcp_code_Client_System = 93 ,/**< Client System N Client System Architecture [RFC4578] */
- dhcp_code_Client_NDI = 94 ,/**< Client NDI N Client Network Device Interface [RFC4578] */
- dhcp_code_LDAP= 95 ,/**< LDAP N Lightweight Directory Access Protocol [RFC3679] */
- dhcp_code_REMOVED_Unassigned= 96 ,/**< REMOVED/Unassigned [RFC3679] */
- dhcp_code_UUID_GUID= 97 ,/**< UUID/GUID N UUID/GUID-based Client Identifier [RFC4578] */
- dhcp_code_User_Auth= 98 ,/**< User-Auth N Open Group's User Authentication [RFC2485] */
- dhcp_code_GEOCONF_CIVIC= 99 ,/**< GEOCONF_CIVIC [RFC4776] */
- dhcp_code_PCode= 100 ,/**< PCode N IEEE 1003.1 TZ String [RFC4833] */
- dhcp_code_TCode= 101 ,/**< TCode N Reference to the TZ Database [RFC4833] */
- //102-107 REMOVED/Unassigned [RFC3679]
- //108 REMOVED/Unassigned [RFC3679]
- //109 Unassigned [RFC3679]
- //110 REMOVED/Unassigned [RFC3679]
- //111 Unassigned [RFC3679]
- dhcp_code_Netinfo_Address= 112 ,/**< Netinfo Address N NetInfo Parent Server Address [RFC3679] */
- dhcp_code_Netinfo_Tag= 113 ,/**< Netinfo Tag N NetInfo Parent Server Tag [RFC3679] */
- dhcp_code_= 114 ,/**< URL N URL [RFC3679] */
- //115 REMOVED/Unassigned [RFC3679]
- dhcp_code_Auto_Config= 116 ,/**< Auto-Config N DHCP Auto-Configuration [RFC2563] */
- dhcp_code_Name_Service_Search= 117 ,/**< Name Service Search N Name Service Search [RFC2937] */
- dhcp_code_Subnet_Selection_Option= 118 ,/**< Subnet Selection Option 4 Subnet Selection Option [RFC3011] */
- dhcp_code_Domain_Search= 119 ,/**< Domain Search N DNS domain search list [RFC3397] */
- dhcp_code_SIP_Servers_DHCP_Option= 120 ,/**< SIP Servers DHCP Option N SIP Servers DHCP Option [RFC3361] */
- dhcp_code_Classless_Static_Route_Option= 121 ,/**< Classless Static Route Option N Classless Static Route Option [RFC3442] */
- dhcp_code_CCC= 122 ,/**< CCC N CableLabs Client Configuration [RFC3495] */
- dhcp_code_GeoConf_Option= 123 ,/**< GeoConf Option 16 GeoConf Option [RFC3825] */
- dhcp_code_V_I_Vendor_Class= 124 ,/**< V-I Vendor Class Vendor-Identifying Vendor Class [RFC3925] */
- dhcp_code_V_I_Vendor_Specific_Information= 125 ,/**< V-I Vendor-Specific Information Vendor-Identifying Vendor-Specific Information [RFC3925] */
- //dhcp_code_= 126 ,/**< Removed/Unassigned [RFC3679] */
- //dhcp_code_= 127 ,/**< Removed/Unassigned [RFC3679] */
- //dhcp_code_PXE - undefined= 128 ,/**< PXE - undefined (vendor specific) [RFC4578] */
- dhcp_code_Etherboot_signature= 128 ,/**< Etherboot signature. 6 bytes: E4:45:74:68:00:00 */
- dhcp_code_DOCSIS= 128 ,/**< DOCSIS "full security" server IP address */
- dhcp_code_TFTP_Server_IP= 128 ,/**< TFTP Server IP address (for IP Phone software load) */
- //dhcp_code_= 129 ,/**< PXE - undefined (vendor specific) [RFC4578] */
- dhcp_code_Kernel_options= 129 ,/**< Kernel options. Variable length string */
- dhcp_code_Call_Server_IP= 129 ,/**< Call Server IP address */
- //dhcp_code_= 130 ,/**< PXE - undefined (vendor specific) [RFC4578] */
- dhcp_code_Ethernet_interface= 130 ,/**< Ethernet interface. Variable length string. */
- dhcp_code_Discrimination= 130 ,/**< Discrimination string (to identify vendor) */
- //dhcp_code_= 131 ,/**< PXE - undefined (vendor specific) [RFC4578] */
- dhcp_code_Remote_statistics_server_IP= 131 ,/**< Remote statistics server IP address */
- //dhcp_code_= 132 ,/**< PXE - undefined (vendor specific) [RFC4578] */
- dhcp_code_IEEE_802_1Q_VLAN_ID= 132 ,/**< IEEE 802.1Q VLAN ID */
- //dhcp_code_= 133 ,/**< PXE - undefined (vendor specific) [RFC4578] */
- dhcp_code_IEEE_802_1D_p= 133 ,/**< IEEE 802.1D/p Layer 2 Priority */
- //dhcp_code_= 134 ,/**< PXE - undefined (vendor specific) [RFC4578] */
- dhcp_code_DSCP= 134 ,/**< Diffserv Code Point (DSCP) for VoIP signalling and media streams */
- //dhcp_code_= 135 ,/**< PXE - undefined (vendor specific) [RFC4578] */
- dhcp_code_HTTP_Proxy= 135 ,/**< HTTP Proxy for phone-specific applications */
- dhcp_code_OPTION_PANA_AGENT= 136 ,/**< OPTION_PANA_AGENT [RFC5192] */
- dhcp_code_OPTION_V4_LOST= 137 ,/**< OPTION_V4_LOST [RFC5223] */
- dhcp_code_OPTION_CAPWAP_AC_V4= 138 ,/**< OPTION_CAPWAP_AC_V4 N CAPWAP Access Controller addresses [RFC5417] */
- dhcp_code_OPTION_IPv4_Address_MoS= 139 ,/**< OPTION-IPv4_Address-MoS N a series of suboptions [RFC5678] */
- dhcp_code_OPTION_IPv4_FQDN_MoS= 140 ,/**< OPTION-IPv4_FQDN-MoS N a series of suboptions [RFC5678] */
- //141-149 Unassigned [RFC3942] */
- dhcp_code_TFTP_server_address= 150 ,/**< TFTP server address (Tentatively Assigned - 2005-06-23) */
- dhcp_code_Etherboot= 150 ,/**< Etherboot */
- dhcp_code_GRUB_configuration_path_name= 150 ,/**< GRUB configuration path name */
- //151-174 Unassigned [RFC3942]
- //dhcp_code_Etherboot= 175 ,/**< Etherboot (Tentatively Assigned - 2005-06-23) */
- dhcp_code_IP_Telephone= 176 ,/**< IP Telephone (Tentatively Assigned - 2005-06-23) */
- //dhcp_code_Etherboot= 177 ,/**< Etherboot (Tentatively Assigned - 2005-06-23) */
- dhcp_code_PacketCable_and_CableHome= 177 ,/**< PacketCable and CableHome (replaced by 122) */
- //178-207 Unassigned [RFC3942]
- dhcp_code_PXELINUX_Magic= 208 ,/**< PXELINUX Magic 4 magic string = F1:00:74:7E [RFC5071] Deprecated */
- dhcp_code_Configuration_File= 209 ,/**< Configuration File N Configuration file [RFC5071] */
- dhcp_code_Path_Prefix= 210 ,/**< Path Prefix N Path Prefix Option [RFC5071] */
- dhcp_code_Reboot_Time = 211 ,/**< Reboot Time 4 Reboot Time [RFC5071] */
- // 212-219 Unassigned
- dhcp_code_Subnet_Allocation= 220 ,/**< Subnet Allocation Option (Tentatively Assigned - 2005-06-23) */
- dhcp_code_Virtual_Subnet= 221 ,/**< Virtual Subnet Selection Option (Tentatively Assigned - 2005-06-23) */
- // 222-223 Unassigned [RFC3942]
- //224-254 Reserved (Private Use)
- dhcp_code_null=224 ,
- dhcp_code_End= 255 ,/**< End 0 None [RFC2132] */
+typedef enum tnet_dhcp_option_code_e {
+ dhcp_code_Pad= 0 ,/**< Pad 0 None [RFC2132] */
+ dhcp_code_Subnet_Mask= 1 ,/**< Subnet Mask 4 Subnet Mask Value [RFC2132] */
+ dhcp_code_Time_Offset= 2 ,/**< Time Offset 4 Time Offset in Seconds from UTC [RFC2132] (note: deprecated by 100 and 101) */
+ dhcp_code_Router= 3 ,/**< Router N N/4 Router addresses [RFC2132] */
+ dhcp_code_Time_Server= 4 ,/**< Time Server N N/4 Timeserver addresses [RFC2132] */
+ dhcp_code_Name_Server= 5 ,/**< Name Server N N/4 IEN-116 Server addresses [RFC2132] */
+ dhcp_code_Domain_Server= 6 ,/**< Domain Server N N/4 DNS Server addresses [RFC2132] */
+ dhcp_code_Log_Server= 7 ,/**< Log Server N N/4 Logging Server addresses [RFC2132] */
+ dhcp_code_Quotes_Server= 8 ,/**< Quotes Server N N/4 Quotes Server addresses [RFC2132] */
+ dhcp_code_LPR_Server= 9 ,/**< LPR Server N N/4 Printer Server addresses [RFC2132] */
+ dhcp_code_Impress_Server= 10 ,/**< Impress Server N N/4 Impress Server addresses [RFC2132] */
+ dhcp_code_RLP_Server= 11 ,/**< RLP Server N N/4 RLP Server addresses [RFC2132] */
+ dhcp_code_Hostname= 12 ,/**< Hostname N Hostname string [RFC2132] */
+ dhcp_code_Boot_File_Size= 13 ,/**< Boot File Size 2 Size of boot file in 512 byte chunks [RFC2132] */
+ dhcp_code_Merit_Dump_File= 14 ,/**< Merit Dump File N Client to dump and name the file to dump it to [RFC2132] */
+ dhcp_code_Domain_Name= 15 ,/**< Domain Name N The DNS domain name of the client [RFC2132] */
+ dhcp_code_Swap_Server= 16 ,/**< Swap Server N Swap Server address [RFC2132] */
+ dhcp_code_Root_Path= 17 ,/**< Root Path N Path name for root disk [RFC2132] */
+ dhcp_code_Extension_File= 18 ,/**< Extension File N Path name for more BOOTP info [RFC2132] */
+ dhcp_code_Forward_On_Off= 19 ,/**< Forward On/Off 1 Enable/Disable IP Forwarding [RFC2132] */
+ dhcp_code_SrcRte_On_Off = 20 ,/**< SrcRte On/Off 1 Enable/Disable Source Routing [RFC2132] */
+ dhcp_code_Policy_Filter= 21 ,/**< Policy Filter N Routing Policy Filters [RFC2132] */
+ dhcp_code_Max_DG_Assembly= 22 ,/**< Max DG Assembly 2 Max Datagram Reassembly Size [RFC2132] */
+ dhcp_code_Default_IP_TTL= 23 ,/**< Default IP TTL 1 Default IP Time to Live [RFC2132] */
+ dhcp_code_MTU_Timeout= 24 ,/**< MTU Timeout 4 Path MTU Aging Timeout [RFC2132] */
+ dhcp_code_MTU_Plateau= 25 ,/**< MTU Plateau N Path MTU Plateau Table [RFC2132] */
+ dhcp_code_MTU_Interface= 26 ,/**< MTU Interface 2 Interface MTU Size [RFC2132] */
+ dhcp_code_MTU_Subnet= 27 ,/**< MTU Subnet 1 All Subnets are Local [RFC2132] */
+ dhcp_code_Broadcast_Address= 28 ,/**< Broadcast Address 4 Broadcast Address [RFC2132] */
+ dhcp_code_Mask_Discovery= 29 ,/**< Mask Discovery 1 Perform Mask Discovery [RFC2132] */
+ dhcp_code_Mask_Supplier= 30 ,/**< Mask Supplier 1 Provide Mask to Others [RFC2132] */
+ dhcp_code_Router_Discovery= 31 ,/**< Router Discovery 1 Perform Router Discovery [RFC2132] */
+ dhcp_code_Router_Request= 32 ,/**< Router Request 4 Router Solicitation Address [RFC2132] */
+ dhcp_code_Static_Route= 33 ,/**< Static Route N Static Routing Table [RFC2132] */
+ dhcp_code_Trailers= 34 ,/**< Trailers 1 Trailer Encapsulation [RFC2132] */
+ dhcp_code_ARP_Timeout= 35 ,/**< ARP Timeout 4 ARP Cache Timeout [RFC2132] */
+ dhcp_code_Ethernet= 36 ,/**< Ethernet 1 Ethernet Encapsulation [RFC2132] */
+ dhcp_code_Default_TCP_TTL= 37 ,/**< Default TCP TTL 1 Default TCP Time to Live [RFC2132] */
+ dhcp_code_Keepalive_Time= 38 ,/**< Keepalive Time 4 TCP Keepalive Interval [RFC2132] */
+ dhcp_code_Keepalive_Data= 39 ,/**< Keepalive Data 1 TCP Keepalive Garbage [RFC2132] */
+ dhcp_code_NIS_Domain= 40 ,/**< NIS Domain N NIS Domain Name [RFC2132] */
+ dhcp_code_NIS_Servers= 41 ,/**< NIS Servers N NIS Server Addresses [RFC2132] */
+ dhcp_code_NTP_Servers= 42 ,/**< NTP Servers N NTP Server Addresses [RFC2132] */
+ dhcp_code_Vendor_Specific= 43 ,/**< Vendor Specific N Vendor Specific Information [RFC2132] */
+ dhcp_code_NETBIOS_Name_Srv= 44 ,/**< NETBIOS Name Srv N NETBIOS Name Servers [RFC2132] */
+ dhcp_code_NETBIOS_Dist_Srv= 45 ,/**< NETBIOS Dist Srv N NETBIOS Datagram Distribution [RFC2132] */
+ dhcp_code_NETBIOS_Node_Type= 46 ,/**< NETBIOS Node Type 1 NETBIOS Node Type [RFC2132] */
+ dhcp_code_NETBIOS_Scope= 47 ,/**< NETBIOS Scope N NETBIOS Scope [RFC2132] */
+ dhcp_code_X_Window_Font= 48 ,/**< X Window Font N X Window Font Server [RFC2132] */
+ dhcp_code_X_Window_Manager= 49 ,/**< X Window Manager N X Window Display Manager [RFC2132] */
+ dhcp_code_Address_Request= 50 ,/**< Address Request 4 Requested IP Address [RFC2132] */
+ dhcp_code_Address_Time= 51 ,/**< Address Time 4 IP Address Lease Time [RFC2132] */
+ dhcp_code_Overload= 52 ,/**< Overload 1 Overload "sname" or "file" [RFC2132] */
+ dhcp_code_DHCP_Msg_Type= 53 ,/**< DHCP Msg Type 1 DHCP Message Type [RFC2132] */
+ dhcp_code_DHCP_Server_Id= 54 ,/**< DHCP Server Id 4 DHCP Server Identification [RFC2132] */
+ dhcp_code_Parameter_List= 55 ,/**< Parameter List N Parameter Request List [RFC2132] */
+ dhcp_code_DHCP_Error_Message= 56 ,/**< DHCP Message N DHCP Error Message [RFC2132] */
+ dhcp_code_DHCP_Max_Msg_Size= 57 ,/**< DHCP Max Msg Size 2 DHCP Maximum Message Size [RFC2132] */
+ dhcp_code_Renewal_Time= 58 ,/**< Renewal Time 4 DHCP Renewal (T1) Time [RFC2132] */
+ dhcp_code_Rebinding_Time= 59 ,/**< Rebinding Time 4 DHCP Rebinding (T2) Time [RFC2132] */
+ dhcp_code_Class_Id= 60 ,/**< Class Id N Class Identifier [RFC2132] */
+ dhcp_code_Client_Id= 61 ,/**< Client Id N Client Identifier [RFC2132] */
+ dhcp_code_NetWare_IP_Domain= 62 ,/**< NetWare/IP Domain N NetWare/IP Domain Name [RFC2242] */
+ dhcp_code_NetWare_IP_Option= 63 ,/**< NetWare/IP Option N NetWare/IP sub Options [RFC2242] */
+ dhcp_code_NIS_Domain_Name= 64 ,/**< NIS-Domain-Name N NIS+ v3 Client Domain Name [RFC2132] */
+ dhcp_code_NIS_Server_Addr = 65 ,/**< NIS-Server-Addr N NIS+ v3 Server Addresses [RFC2132] */
+ dhcp_code_Server_Name= 66 ,/**< Server-Name N TFTP Server Name [RFC2132] */
+ dhcp_code_Bootfile_Name= 67 ,/**< Bootfile-Name N Boot File Name [RFC2132] */
+ dhcp_code_Home_Agent_Addrs= 68 ,/**< Home-Agent-Addrs N Home Agent Addresses [RFC2132] */
+ dhcp_code_SMTP_Server= 69 ,/**< SMTP-Server N Simple Mail Server Addresses [RFC2132] */
+ dhcp_code_POP3_Server= 70 ,/**< POP3-Server N Post Office Server Addresses [RFC2132] */
+ dhcp_code_NNTP_Server= 71 ,/**< NNTP-Server N Network News Server Addresses [RFC2132] */
+ dhcp_code_WWW_Server= 72 ,/**< WWW-Server N WWW Server Addresses [RFC2132] */
+ dhcp_code_Finger_Server= 73 ,/**< Finger-Server N Finger Server Addresses [RFC2132] */
+ dhcp_code_IRC_Server= 74 ,/**< IRC-Server N Chat Server Addresses [RFC2132] */
+ dhcp_code_StreetTalk_Server= 75 ,/**< StreetTalk-Server N StreetTalk Server Addresses [RFC2132] */
+ dhcp_code_STDA_Server= 76 ,/**< STDA-Server N ST Directory Assist. Addresses [RFC2132] */
+ dhcp_code_User_Class= 77 ,/**< User-Class N User Class Information [RFC3004] */
+ dhcp_code_Directory_Agent = 78 ,/**< Directory Agent N directory agent information [RFC2610] */
+ dhcp_code_Service_Scope = 79 ,/**< Service Scope N service location agent scope [RFC2610] */
+ dhcp_code_Rapid_Commit= 80 ,/**< Rapid Commit 0 Rapid Commit [RFC4039] */
+ dhcp_code_Client_FQDN = 81 ,/**< Client FQDN N Fully Qualified Domain Name [RFC4702] */
+ dhcp_code_Relay_Agent_Information= 82 ,/**< Relay Agent Information N Relay Agent Information [RFC3046] */
+ dhcp_code_iSNS= 83 ,/**< iSNS N Internet Storage Name Service [RFC4174] */
+ //84 REMOVED/Unassigned [RFC3679] */
+ dhcp_code_NDS_Servers= 85 ,/**< NDS Servers N Novell Directory Services [RFC2241] */
+ dhcp_code_NDS_Tree_Name= 86 ,/**< NDS Tree Name N Novell Directory Services [RFC2241] */
+ dhcp_code_NDS_Context= 87 ,/**< NDS Context N Novell Directory Services [RFC2241] */
+ dhcp_code_BCMCS_Controller_Domain_Name_list= 88 ,/**< BCMCS Controller Domain Name list [RFC4280] */
+ dhcp_code_BCMCS_Controller_IPv4_address_option= 89 ,/**< BCMCS Controller IPv4 address option [RFC4280] */
+ dhcp_code_Authentication= 90 ,/**< Authentication N Authentication [RFC3118] */
+ dhcp_code_client_last_transaction_time= 91 ,/**< client-last-transaction-time option [RFC4388] */
+ dhcp_code_associated_ip= 92 ,/**< associated-ip option [RFC4388] */
+ dhcp_code_Client_System = 93 ,/**< Client System N Client System Architecture [RFC4578] */
+ dhcp_code_Client_NDI = 94 ,/**< Client NDI N Client Network Device Interface [RFC4578] */
+ dhcp_code_LDAP= 95 ,/**< LDAP N Lightweight Directory Access Protocol [RFC3679] */
+ dhcp_code_REMOVED_Unassigned= 96 ,/**< REMOVED/Unassigned [RFC3679] */
+ dhcp_code_UUID_GUID= 97 ,/**< UUID/GUID N UUID/GUID-based Client Identifier [RFC4578] */
+ dhcp_code_User_Auth= 98 ,/**< User-Auth N Open Group's User Authentication [RFC2485] */
+ dhcp_code_GEOCONF_CIVIC= 99 ,/**< GEOCONF_CIVIC [RFC4776] */
+ dhcp_code_PCode= 100 ,/**< PCode N IEEE 1003.1 TZ String [RFC4833] */
+ dhcp_code_TCode= 101 ,/**< TCode N Reference to the TZ Database [RFC4833] */
+ //102-107 REMOVED/Unassigned [RFC3679]
+ //108 REMOVED/Unassigned [RFC3679]
+ //109 Unassigned [RFC3679]
+ //110 REMOVED/Unassigned [RFC3679]
+ //111 Unassigned [RFC3679]
+ dhcp_code_Netinfo_Address= 112 ,/**< Netinfo Address N NetInfo Parent Server Address [RFC3679] */
+ dhcp_code_Netinfo_Tag= 113 ,/**< Netinfo Tag N NetInfo Parent Server Tag [RFC3679] */
+ dhcp_code_= 114 ,/**< URL N URL [RFC3679] */
+ //115 REMOVED/Unassigned [RFC3679]
+ dhcp_code_Auto_Config= 116 ,/**< Auto-Config N DHCP Auto-Configuration [RFC2563] */
+ dhcp_code_Name_Service_Search= 117 ,/**< Name Service Search N Name Service Search [RFC2937] */
+ dhcp_code_Subnet_Selection_Option= 118 ,/**< Subnet Selection Option 4 Subnet Selection Option [RFC3011] */
+ dhcp_code_Domain_Search= 119 ,/**< Domain Search N DNS domain search list [RFC3397] */
+ dhcp_code_SIP_Servers_DHCP_Option= 120 ,/**< SIP Servers DHCP Option N SIP Servers DHCP Option [RFC3361] */
+ dhcp_code_Classless_Static_Route_Option= 121 ,/**< Classless Static Route Option N Classless Static Route Option [RFC3442] */
+ dhcp_code_CCC= 122 ,/**< CCC N CableLabs Client Configuration [RFC3495] */
+ dhcp_code_GeoConf_Option= 123 ,/**< GeoConf Option 16 GeoConf Option [RFC3825] */
+ dhcp_code_V_I_Vendor_Class= 124 ,/**< V-I Vendor Class Vendor-Identifying Vendor Class [RFC3925] */
+ dhcp_code_V_I_Vendor_Specific_Information= 125 ,/**< V-I Vendor-Specific Information Vendor-Identifying Vendor-Specific Information [RFC3925] */
+ //dhcp_code_= 126 ,/**< Removed/Unassigned [RFC3679] */
+ //dhcp_code_= 127 ,/**< Removed/Unassigned [RFC3679] */
+ //dhcp_code_PXE - undefined= 128 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_Etherboot_signature= 128 ,/**< Etherboot signature. 6 bytes: E4:45:74:68:00:00 */
+ dhcp_code_DOCSIS= 128 ,/**< DOCSIS "full security" server IP address */
+ dhcp_code_TFTP_Server_IP= 128 ,/**< TFTP Server IP address (for IP Phone software load) */
+ //dhcp_code_= 129 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_Kernel_options= 129 ,/**< Kernel options. Variable length string */
+ dhcp_code_Call_Server_IP= 129 ,/**< Call Server IP address */
+ //dhcp_code_= 130 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_Ethernet_interface= 130 ,/**< Ethernet interface. Variable length string. */
+ dhcp_code_Discrimination= 130 ,/**< Discrimination string (to identify vendor) */
+ //dhcp_code_= 131 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_Remote_statistics_server_IP= 131 ,/**< Remote statistics server IP address */
+ //dhcp_code_= 132 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_IEEE_802_1Q_VLAN_ID= 132 ,/**< IEEE 802.1Q VLAN ID */
+ //dhcp_code_= 133 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_IEEE_802_1D_p= 133 ,/**< IEEE 802.1D/p Layer 2 Priority */
+ //dhcp_code_= 134 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_DSCP= 134 ,/**< Diffserv Code Point (DSCP) for VoIP signalling and media streams */
+ //dhcp_code_= 135 ,/**< PXE - undefined (vendor specific) [RFC4578] */
+ dhcp_code_HTTP_Proxy= 135 ,/**< HTTP Proxy for phone-specific applications */
+ dhcp_code_OPTION_PANA_AGENT= 136 ,/**< OPTION_PANA_AGENT [RFC5192] */
+ dhcp_code_OPTION_V4_LOST= 137 ,/**< OPTION_V4_LOST [RFC5223] */
+ dhcp_code_OPTION_CAPWAP_AC_V4= 138 ,/**< OPTION_CAPWAP_AC_V4 N CAPWAP Access Controller addresses [RFC5417] */
+ dhcp_code_OPTION_IPv4_Address_MoS= 139 ,/**< OPTION-IPv4_Address-MoS N a series of suboptions [RFC5678] */
+ dhcp_code_OPTION_IPv4_FQDN_MoS= 140 ,/**< OPTION-IPv4_FQDN-MoS N a series of suboptions [RFC5678] */
+ //141-149 Unassigned [RFC3942] */
+ dhcp_code_TFTP_server_address= 150 ,/**< TFTP server address (Tentatively Assigned - 2005-06-23) */
+ dhcp_code_Etherboot= 150 ,/**< Etherboot */
+ dhcp_code_GRUB_configuration_path_name= 150 ,/**< GRUB configuration path name */
+ //151-174 Unassigned [RFC3942]
+ //dhcp_code_Etherboot= 175 ,/**< Etherboot (Tentatively Assigned - 2005-06-23) */
+ dhcp_code_IP_Telephone= 176 ,/**< IP Telephone (Tentatively Assigned - 2005-06-23) */
+ //dhcp_code_Etherboot= 177 ,/**< Etherboot (Tentatively Assigned - 2005-06-23) */
+ dhcp_code_PacketCable_and_CableHome= 177 ,/**< PacketCable and CableHome (replaced by 122) */
+ //178-207 Unassigned [RFC3942]
+ dhcp_code_PXELINUX_Magic= 208 ,/**< PXELINUX Magic 4 magic string = F1:00:74:7E [RFC5071] Deprecated */
+ dhcp_code_Configuration_File= 209 ,/**< Configuration File N Configuration file [RFC5071] */
+ dhcp_code_Path_Prefix= 210 ,/**< Path Prefix N Path Prefix Option [RFC5071] */
+ dhcp_code_Reboot_Time = 211 ,/**< Reboot Time 4 Reboot Time [RFC5071] */
+ // 212-219 Unassigned
+ dhcp_code_Subnet_Allocation= 220 ,/**< Subnet Allocation Option (Tentatively Assigned - 2005-06-23) */
+ dhcp_code_Virtual_Subnet= 221 ,/**< Virtual Subnet Selection Option (Tentatively Assigned - 2005-06-23) */
+ // 222-223 Unassigned [RFC3942]
+ //224-254 Reserved (Private Use)
+ dhcp_code_null=224 ,
+ dhcp_code_End= 255 ,/**< End 0 None [RFC2132] */
}
tnet_dhcp_option_code_t;
/** DHCP/BOOTP option as per RFC 2132.
* Format ==> subclause 2.
*/
-typedef struct tnet_dhcp_option_s
-{
- TSK_DECLARE_OBJECT;
-
- tsk_bool_t initialized;
-
- tnet_dhcp_option_code_t code; /**< 1-byte option-code. */
- tsk_buffer_t *value;
+typedef struct tnet_dhcp_option_s {
+ TSK_DECLARE_OBJECT;
+
+ tsk_bool_t initialized;
+
+ tnet_dhcp_option_code_t code; /**< 1-byte option-code. */
+ tsk_buffer_t *value;
}
tnet_dhcp_option_t;
@@ -243,16 +241,15 @@ int tnet_dhcp_option_serializeex(tnet_dhcp_option_code_t code, uint8_t length, c
*=======================================================================================*/
/** Parameter Request List Option */
-typedef struct tnet_dhcp_option_paramslist_s
-{
- TNET_DECLARE_DHCP_OPTION;
+typedef struct tnet_dhcp_option_paramslist_s {
+ TNET_DECLARE_DHCP_OPTION;
- /* RFC 2132 - 9.8. Parameter Request List
- Code Len Option Codes
- +-----+-----+-----+-----+---
- | 55 | n | c1 | c2 | ...
- +-----+-----+-----+-----+---
- */
+ /* RFC 2132 - 9.8. Parameter Request List
+ Code Len Option Codes
+ +-----+-----+-----+-----+---
+ | 55 | n | c1 | c2 | ...
+ +-----+-----+-----+-----+---
+ */
}
tnet_dhcp_option_paramslist_t;
int tnet_dhcp_option_paramslist_add_code(tnet_dhcp_option_paramslist_t* self, tnet_dhcp_option_code_t code);
@@ -262,17 +259,16 @@ int tnet_dhcp_option_paramslist_add_code(tnet_dhcp_option_paramslist_t* self, tn
*=======================================================================================*/
/** Domain Name Server Option */
-typedef struct tnet_dhcp_option_dns_s
-{
- TNET_DECLARE_DHCP_OPTION;
+typedef struct tnet_dhcp_option_dns_s {
+ TNET_DECLARE_DHCP_OPTION;
- /* RFC 2132 - 3.8. Domain Name Server Option
- Code Len Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- */
- tsk_strings_L_t *servers;
+ /* RFC 2132 - 3.8. Domain Name Server Option
+ Code Len Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 6 | n | a1 | a2 | a3 | a4 | a1 | a2 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ tsk_strings_L_t *servers;
}
tnet_dhcp_option_dns_t;
diff --git a/tinyNET/src/dhcp/tnet_dhcp_option_sip.c b/tinyNET/src/dhcp/tnet_dhcp_option_sip.c
index 0c763fb..bbfd39a 100755
--- a/tinyNET/src/dhcp/tnet_dhcp_option_sip.c
+++ b/tinyNET/src/dhcp/tnet_dhcp_option_sip.c
@@ -2,25 +2,25 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tnet_dhcp_option_sip.c
- * @brief Dynamic Host Configuration Protocol (DHCP-for-IPv4) Option for
+ * @brief Dynamic Host Configuration Protocol (DHCP-for-IPv4) Option for
* Session Initiation Protocol (SIP) Servers as per RFC 3361.
*
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
@@ -39,7 +39,7 @@
tnet_dhcp_option_sip_t* tnet_dhcp_option_sip_create(const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp_option_sip_def_t, payload, payload_size);
+ return tsk_object_new(tnet_dhcp_option_sip_def_t, payload, payload_size);
}
//
@@ -47,85 +47,84 @@ tnet_dhcp_option_sip_t* tnet_dhcp_option_sip_create(const void* payload, tsk_siz
//
static tsk_object_t* tnet_dhcp_option_sip_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp_option_sip_t *option = self;
- if(option){
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- const uint8_t* payloadPtr = (const uint8_t*)payload;
- const uint8_t* payloadEnd = (payloadPtr + payload_size);
-
- /* init base */
- tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_SIP_Servers_DHCP_Option);
-
- option->servers = tsk_list_create();
-
- /* Set values as per RFC 3361. */
- if(*payloadPtr == 0){ /* enc=0 */
- /*
- +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- |120|27 | 0 | 7 |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'c'|'o'|'m'| 0 |
- +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
- +---+---+---+---+---+---+---+---+---+---+---+---+---+ | 7
- |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'n'|'e'|'t'| 0 | +---+---+---
- +---+---+---+---+---+---+---+---+---+---+
- */
- tsk_size_t offset = 1;
- char* server = 0;
- payloadPtr++;
- while((payloadPtr < payloadEnd) && !tnet_dns_rr_qname_deserialize(payload, &server, &offset)){
- tsk_string_t* string = tsk_string_create(server);
- tsk_list_push_back_data(option->servers, (void*)&string);
- TSK_FREE(server);
- payloadPtr += offset;
- }
- }
- else{
- /*
- Code Len enc Address 1 Address 2
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 120 | n | 1 | a1 | a2 | a3 | a4 | a1 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- */
- uint32_t address;
- tsk_string_t* addrstring;
- char* ip4 = 0;
-
- while(payloadPtr < payloadEnd){
- ++payloadPtr;
- address = (uint32_t)tnet_htonl_2(payloadPtr);
-
- tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
-
- addrstring = tsk_string_create(ip4);
- tsk_list_push_back_data(option->servers, (void*)&addrstring);
-
- TSK_FREE(ip4);
-
- payloadPtr+= 4;
- }
- }
- }
- return self;
-}
+ tnet_dhcp_option_sip_t *option = self;
+ if(option) {
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ const uint8_t* payloadPtr = (const uint8_t*)payload;
+ const uint8_t* payloadEnd = (payloadPtr + payload_size);
+
+ /* init base */
+ tnet_dhcp_option_init(TNET_DHCP_OPTION(option), dhcp_code_SIP_Servers_DHCP_Option);
+
+ option->servers = tsk_list_create();
-static tsk_object_t* tnet_dhcp_option_sip_dtor(tsk_object_t * self)
-{
- tnet_dhcp_option_sip_t *option = self;
- if(option){
- /* deinit base */
- tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
+ /* Set values as per RFC 3361. */
+ if(*payloadPtr == 0) { /* enc=0 */
+ /*
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ |120|27 | 0 | 7 |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'c'|'o'|'m'| 0 |
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
+ +---+---+---+---+---+---+---+---+---+---+---+---+---+ | 7
+ |'e'|'x'|'a'|'m'|'p'|'l'|'e'| 3 |'n'|'e'|'t'| 0 | +---+---+---
+ +---+---+---+---+---+---+---+---+---+---+
+ */
+ tsk_size_t offset = 1;
+ char* server = 0;
+ payloadPtr++;
+ while((payloadPtr < payloadEnd) && !tnet_dns_rr_qname_deserialize(payload, &server, &offset)) {
+ tsk_string_t* string = tsk_string_create(server);
+ tsk_list_push_back_data(option->servers, (void*)&string);
+ TSK_FREE(server);
+ payloadPtr += offset;
+ }
+ }
+ else {
+ /*
+ Code Len enc Address 1 Address 2
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 120 | n | 1 | a1 | a2 | a3 | a4 | a1 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ uint32_t address;
+ tsk_string_t* addrstring;
+ char* ip4 = 0;
- TSK_OBJECT_SAFE_FREE(option->servers);
- }
- return self;
+ while(payloadPtr < payloadEnd) {
+ ++payloadPtr;
+ address = (uint32_t)tnet_htonl_2(payloadPtr);
+
+ tsk_sprintf(&ip4, "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
+
+ addrstring = tsk_string_create(ip4);
+ tsk_list_push_back_data(option->servers, (void*)&addrstring);
+
+ TSK_FREE(ip4);
+
+ payloadPtr+= 4;
+ }
+ }
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp_option_sip_def_s =
+static tsk_object_t* tnet_dhcp_option_sip_dtor(tsk_object_t * self)
{
- sizeof(tnet_dhcp_option_sip_t),
- tnet_dhcp_option_sip_ctor,
- tnet_dhcp_option_sip_dtor,
- tsk_null,
+ tnet_dhcp_option_sip_t *option = self;
+ if(option) {
+ /* deinit base */
+ tnet_dhcp_option_deinit(TNET_DHCP_OPTION(option));
+
+ TSK_OBJECT_SAFE_FREE(option->servers);
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp_option_sip_def_s = {
+ sizeof(tnet_dhcp_option_sip_t),
+ tnet_dhcp_option_sip_ctor,
+ tnet_dhcp_option_sip_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp_option_sip_def_t = &tnet_dhcp_option_sip_def_s;
diff --git a/tinyNET/src/dhcp/tnet_dhcp_option_sip.h b/tinyNET/src/dhcp/tnet_dhcp_option_sip.h
index 2e35bf5..f08c2e6 100755
--- a/tinyNET/src/dhcp/tnet_dhcp_option_sip.h
+++ b/tinyNET/src/dhcp/tnet_dhcp_option_sip.h
@@ -2,25 +2,25 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
*/
/**@file tnet_dhcp_option_sip.h
- * @brief Dynamic Host Configuration Protocol (DHCP-for-IPv4) Option for
+ * @brief Dynamic Host Configuration Protocol (DHCP-for-IPv4) Option for
* Session Initiation Protocol (SIP) Servers as per RFC 3361.
*
* @author Mamadou Diop <diopmamadou(at)doubango[dot]org>
@@ -39,17 +39,16 @@
TNET_BEGIN_DECLS
-typedef struct tnet_dhcp_option_sip_s
-{
- TNET_DECLARE_DHCP_OPTION;
-
- /* RFC 3361 subclause 3.1
- Code Len enc DNS name of SIP server
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- | 120 | n | 0 | s1 | s2 | s3 | s4 | s5 | ...
- +-----+-----+-----+-----+-----+-----+-----+-----+--
- */
- tsk_strings_L_t *servers;
+typedef struct tnet_dhcp_option_sip_s {
+ TNET_DECLARE_DHCP_OPTION;
+
+ /* RFC 3361 subclause 3.1
+ Code Len enc DNS name of SIP server
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ | 120 | n | 0 | s1 | s2 | s3 | s4 | s5 | ...
+ +-----+-----+-----+-----+-----+-----+-----+-----+--
+ */
+ tsk_strings_L_t *servers;
}
tnet_dhcp_option_sip_t;
diff --git a/tinyNET/src/dhcp6/tnet_dhcp6.c b/tinyNET/src/dhcp6/tnet_dhcp6.c
index 8e2fdb7..94bf8cc 100755
--- a/tinyNET/src/dhcp6/tnet_dhcp6.c
+++ b/tinyNET/src/dhcp6/tnet_dhcp6.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -43,145 +43,144 @@
tnet_dhcp6_ctx_t* tnet_dhcp6_ctx_create()
{
- return tsk_object_new(tnet_dhcp6_ctx_def_t);
+ return tsk_object_new(tnet_dhcp6_ctx_def_t);
}
/**@ingroup tnet_dhcp6_group
*/
tnet_dhcp6_reply_t* tnet_dhcp6_send_request(const tnet_dhcp6_ctx_t* ctx, tnet_dhcp6_request_t* request)
{
- tsk_buffer_t *output;
- tnet_dhcp6_reply_t* reply = 0;
- int ret;
- struct timeval tv;
- fd_set set;
- uint64_t timeout = 0;
- tsk_list_item_t *item;
- const tnet_interface_t *iface;
- tnet_ip_t bestsource;
-
- tnet_socket_t *localsocket6 = 0;
- struct sockaddr_storage server;
-
- if(!ctx || !request){
- goto bail;
- }
-
- if((ret = tnet_getbestsource(TNET_DHCP6_All_DHCP_Relay_Agents_and_Servers, ctx->server_port, tnet_socket_type_udp_ipv6, &bestsource))){
- TSK_DEBUG_WARN("Failed to get best source for [%s]:%u.", TNET_DHCP6_All_DHCP_Relay_Agents_and_Servers, ctx->server_port);
- //fe80::21b:63ff:fea9:c14e%4
- localsocket6 = tnet_socket_create(TNET_SOCKET_HOST_ANY, ctx->port_client, tnet_socket_type_udp_ipv6);
- }
- else{
- localsocket6 = tnet_socket_create(bestsource, ctx->port_client, tnet_socket_type_udp_ipv6);
- }
-
- /* Check local socket. */
- if(!TNET_SOCKET_IS_VALID(localsocket6)){
- TSK_DEBUG_ERROR("Failed to create/bind DHCPv6 client socket.");
- goto bail;
- }
-
- /* Always wait for 200ms before retransmission */
- tv.tv_sec = 0;
- tv.tv_usec = (200 * 1000);
-
- if(tnet_sockaddr_init(TNET_DHCP6_All_DHCP_Relay_Agents_and_Servers, ctx->server_port, tnet_socket_type_udp_ipv6, &server)){
- TNET_PRINT_LAST_ERROR("Failed to initialize the DHCPv6 server address.");
- goto bail;
- }
-
- /* Set timeout */
- timeout = tsk_time_epoch() + ctx->timeout;
-
- do
- {
- tsk_list_foreach(item, ctx->interfaces){
- iface = item->data;
-
- /* Set FD */
- FD_ZERO(&set);
- FD_SET(localsocket6->fd, &set);
-
- ///* ciaddr */
- //if(request->type == dhcp_type_inform){
- // struct sockaddr_storage ss;
- // if(!tnet_get_sockaddr(localsocket4->fd, &ss)){
- // uint32_t addr = tnet_htonl_2(&((struct sockaddr_in*)&ss)->sin_addr);
- // memcpy(&request->ciaddr, &addr, 4);
- // }
- //}
-
- ///* chaddr */
- //memset(request->chaddr, 0, sizeof(request->chaddr));
- //request->hlen = iface->mac_address_length > sizeof(request->chaddr) ? sizeof(request->chaddr) : iface->mac_address_length;
- //memcpy(request->chaddr, iface->mac_address, request->hlen);
-
- /* Serialize and send to the server. */
- if(!(output = tnet_dhcp6_message_serialize(ctx, request))){
- TSK_DEBUG_ERROR("Failed to serialize the DHCPv6 message.");
- goto next_iface;
- }
- /* Send the request to the DHCP server */
- if((ret =tnet_sockfd_sendto(localsocket6->fd, (const struct sockaddr*)&server, output->data, output->size))<0){
- TNET_PRINT_LAST_ERROR("Failed to send DHCPv6 request.");
-
- tsk_thread_sleep(150); // wait 150ms before trying the next iface.
- goto next_iface;
- }
- /* wait for response */
- if((ret = select(localsocket6->fd+1, &set, NULL, NULL, &tv))<0){ /* Error */
- TNET_PRINT_LAST_ERROR("select have failed.");
- tsk_thread_sleep(150); // wait 150ms before trying the next iface.
- goto next_iface;
- }
- else if(ret == 0){ /* timeout ==> do nothing */
- }
- else{ /* there is data to read. */
- unsigned int len = 0;
- void* data = 0;
-
- /* Check how how many bytes are pending */
- if((ret = tnet_ioctlt(localsocket6->fd, FIONREAD, &len))<0){
- goto next_iface;
- }
-
- /* Receive pending data */
- data = tsk_calloc(len, sizeof(uint8_t));
- if((ret = tnet_sockfd_recv(localsocket6->fd, data, len, 0))<0){
- TSK_FREE(data);
-
- TNET_PRINT_LAST_ERROR("Failed to receive DHCP dgrams.");
- goto next_iface;
- }
-
- /* Parse the incoming response. */
- reply = tnet_dhcp6_message_deserialize(ctx, data, (tsk_size_t)ret);
- TSK_FREE(data);
-
- if(reply)
- { /* response successfuly parsed */
- if(request->transaction_id != reply->transaction_id)
- { /* Not same transaction id ==> continue*/
- TSK_OBJECT_SAFE_FREE(reply);
- }
- }
- }
-
- next_iface:
- TSK_OBJECT_SAFE_FREE(output);
- if(reply){
- goto bail;
- }
- }
- break;//FIXME
- }
- while(timeout > tsk_time_epoch());
+ tsk_buffer_t *output;
+ tnet_dhcp6_reply_t* reply = 0;
+ int ret;
+ struct timeval tv;
+ fd_set set;
+ uint64_t timeout = 0;
+ tsk_list_item_t *item;
+ const tnet_interface_t *iface;
+ tnet_ip_t bestsource;
+
+ tnet_socket_t *localsocket6 = 0;
+ struct sockaddr_storage server;
+
+ if(!ctx || !request) {
+ goto bail;
+ }
+
+ if((ret = tnet_getbestsource(TNET_DHCP6_All_DHCP_Relay_Agents_and_Servers, ctx->server_port, tnet_socket_type_udp_ipv6, &bestsource))) {
+ TSK_DEBUG_WARN("Failed to get best source for [%s]:%u.", TNET_DHCP6_All_DHCP_Relay_Agents_and_Servers, ctx->server_port);
+ //fe80::21b:63ff:fea9:c14e%4
+ localsocket6 = tnet_socket_create(TNET_SOCKET_HOST_ANY, ctx->port_client, tnet_socket_type_udp_ipv6);
+ }
+ else {
+ localsocket6 = tnet_socket_create(bestsource, ctx->port_client, tnet_socket_type_udp_ipv6);
+ }
+
+ /* Check local socket. */
+ if(!TNET_SOCKET_IS_VALID(localsocket6)) {
+ TSK_DEBUG_ERROR("Failed to create/bind DHCPv6 client socket.");
+ goto bail;
+ }
+
+ /* Always wait for 200ms before retransmission */
+ tv.tv_sec = 0;
+ tv.tv_usec = (200 * 1000);
+
+ if(tnet_sockaddr_init(TNET_DHCP6_All_DHCP_Relay_Agents_and_Servers, ctx->server_port, tnet_socket_type_udp_ipv6, &server)) {
+ TNET_PRINT_LAST_ERROR("Failed to initialize the DHCPv6 server address.");
+ goto bail;
+ }
+
+ /* Set timeout */
+ timeout = tsk_time_epoch() + ctx->timeout;
+
+ do {
+ tsk_list_foreach(item, ctx->interfaces) {
+ iface = item->data;
+
+ /* Set FD */
+ FD_ZERO(&set);
+ FD_SET(localsocket6->fd, &set);
+
+ ///* ciaddr */
+ //if(request->type == dhcp_type_inform){
+ // struct sockaddr_storage ss;
+ // if(!tnet_get_sockaddr(localsocket4->fd, &ss)){
+ // uint32_t addr = tnet_htonl_2(&((struct sockaddr_in*)&ss)->sin_addr);
+ // memcpy(&request->ciaddr, &addr, 4);
+ // }
+ //}
+
+ ///* chaddr */
+ //memset(request->chaddr, 0, sizeof(request->chaddr));
+ //request->hlen = iface->mac_address_length > sizeof(request->chaddr) ? sizeof(request->chaddr) : iface->mac_address_length;
+ //memcpy(request->chaddr, iface->mac_address, request->hlen);
+
+ /* Serialize and send to the server. */
+ if(!(output = tnet_dhcp6_message_serialize(ctx, request))) {
+ TSK_DEBUG_ERROR("Failed to serialize the DHCPv6 message.");
+ goto next_iface;
+ }
+ /* Send the request to the DHCP server */
+ if((ret =tnet_sockfd_sendto(localsocket6->fd, (const struct sockaddr*)&server, output->data, output->size))<0) {
+ TNET_PRINT_LAST_ERROR("Failed to send DHCPv6 request.");
+
+ tsk_thread_sleep(150); // wait 150ms before trying the next iface.
+ goto next_iface;
+ }
+ /* wait for response */
+ if((ret = select(localsocket6->fd+1, &set, NULL, NULL, &tv))<0) { /* Error */
+ TNET_PRINT_LAST_ERROR("select have failed.");
+ tsk_thread_sleep(150); // wait 150ms before trying the next iface.
+ goto next_iface;
+ }
+ else if(ret == 0) { /* timeout ==> do nothing */
+ }
+ else { /* there is data to read. */
+ unsigned int len = 0;
+ void* data = 0;
+
+ /* Check how how many bytes are pending */
+ if((ret = tnet_ioctlt(localsocket6->fd, FIONREAD, &len))<0) {
+ goto next_iface;
+ }
+
+ /* Receive pending data */
+ data = tsk_calloc(len, sizeof(uint8_t));
+ if((ret = tnet_sockfd_recv(localsocket6->fd, data, len, 0))<0) {
+ TSK_FREE(data);
+
+ TNET_PRINT_LAST_ERROR("Failed to receive DHCP dgrams.");
+ goto next_iface;
+ }
+
+ /* Parse the incoming response. */
+ reply = tnet_dhcp6_message_deserialize(ctx, data, (tsk_size_t)ret);
+ TSK_FREE(data);
+
+ if(reply) {
+ /* response successfuly parsed */
+ if(request->transaction_id != reply->transaction_id) {
+ /* Not same transaction id ==> continue*/
+ TSK_OBJECT_SAFE_FREE(reply);
+ }
+ }
+ }
+
+next_iface:
+ TSK_OBJECT_SAFE_FREE(output);
+ if(reply) {
+ goto bail;
+ }
+ }
+ break;//FIXME
+ }
+ while(timeout > tsk_time_epoch());
bail:
- TSK_OBJECT_SAFE_FREE(localsocket6);
+ TSK_OBJECT_SAFE_FREE(localsocket6);
- return reply;
+ return reply;
}
@@ -193,28 +192,28 @@ bail:
*/
tnet_dhcp6_reply_t* tnet_dhcp6_requestinfo(const tnet_dhcp6_ctx_t* ctx, const tnet_dhcp6_option_orequest_t *orequest)
{
- tnet_dhcp6_reply_t* reply = 0;
- tnet_dhcp6_request_t* request = tnet_dhcp6_request_create(dhcp6_type_information_request);
- tnet_dhcp6_option_t* option = 0;
+ tnet_dhcp6_reply_t* reply = 0;
+ tnet_dhcp6_request_t* request = tnet_dhcp6_request_create(dhcp6_type_information_request);
+ tnet_dhcp6_option_t* option = 0;
- if(!ctx || !orequest || !request){
- goto bail;
- }
+ if(!ctx || !orequest || !request) {
+ goto bail;
+ }
- if((option = tnet_dhcp6_option_create(dhcp6_code_oro, orequest, sizeof(*orequest)))){
- tsk_list_push_back_data(request->options, (void**)&option);
- }
+ if((option = tnet_dhcp6_option_create(dhcp6_code_oro, orequest, sizeof(*orequest)))) {
+ tsk_list_push_back_data(request->options, (void**)&option);
+ }
- /* Vendor class */
- {
-
- }
+ /* Vendor class */
+ {
- reply = tnet_dhcp6_send_request(ctx, request);
+ }
+
+ reply = tnet_dhcp6_send_request(ctx, request);
bail:
- return reply;
+ return reply;
}
@@ -226,44 +225,43 @@ bail:
//
static tsk_object_t* tnet_dhcp6_ctx_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_ctx_t *ctx = self;
- if(ctx){
- ctx->pen = TNET_IANA_PEN;
- ctx->vendor_class_data = tsk_strdup(TNET_DHCP6_VENDOR_CLASS_DATA_DEFAULT);
-
- ctx->port_client = TNET_DHCP6_CLIENT_PORT;
- ctx->server_port = TNET_DHCP6_SERVER_PORT;
- ctx->interfaces = tnet_get_interfaces();
-
- ctx->timeout = 0xffff; /* FIXME */
-
- if(!ctx->interfaces || TSK_LIST_IS_EMPTY(ctx->interfaces)){
- TSK_DEBUG_ERROR("Failed to retrieve network interfaces.");
- }
-
- tsk_safeobj_init(ctx);
- }
- return self;
-}
+ tnet_dhcp6_ctx_t *ctx = self;
+ if(ctx) {
+ ctx->pen = TNET_IANA_PEN;
+ ctx->vendor_class_data = tsk_strdup(TNET_DHCP6_VENDOR_CLASS_DATA_DEFAULT);
+
+ ctx->port_client = TNET_DHCP6_CLIENT_PORT;
+ ctx->server_port = TNET_DHCP6_SERVER_PORT;
+ ctx->interfaces = tnet_get_interfaces();
-static tsk_object_t* tnet_dhcp6_ctx_dtor(tsk_object_t * self)
-{
- tnet_dhcp6_ctx_t *ctx = self;
- if(ctx){
- tsk_safeobj_deinit(ctx);
-
- TSK_FREE(ctx->vendor_class_data);
-
- TSK_OBJECT_SAFE_FREE(ctx->interfaces);
- }
- return self;
+ ctx->timeout = 0xffff; /* FIXME */
+
+ if(!ctx->interfaces || TSK_LIST_IS_EMPTY(ctx->interfaces)) {
+ TSK_DEBUG_ERROR("Failed to retrieve network interfaces.");
+ }
+
+ tsk_safeobj_init(ctx);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_ctx_def_s =
+static tsk_object_t* tnet_dhcp6_ctx_dtor(tsk_object_t * self)
{
- sizeof(tnet_dhcp6_ctx_t),
- tnet_dhcp6_ctx_ctor,
- tnet_dhcp6_ctx_dtor,
- tsk_null,
+ tnet_dhcp6_ctx_t *ctx = self;
+ if(ctx) {
+ tsk_safeobj_deinit(ctx);
+
+ TSK_FREE(ctx->vendor_class_data);
+
+ TSK_OBJECT_SAFE_FREE(ctx->interfaces);
+ }
+ return self;
+}
+
+static const tsk_object_def_t tnet_dhcp6_ctx_def_s = {
+ sizeof(tnet_dhcp6_ctx_t),
+ tnet_dhcp6_ctx_ctor,
+ tnet_dhcp6_ctx_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_ctx_def_t = &tnet_dhcp6_ctx_def_s;
diff --git a/tinyNET/src/dhcp6/tnet_dhcp6.h b/tinyNET/src/dhcp6/tnet_dhcp6.h
index 156f5a9..fa556f8 100755
--- a/tinyNET/src/dhcp6/tnet_dhcp6.h
+++ b/tinyNET/src/dhcp6/tnet_dhcp6.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -61,7 +61,7 @@ TNET_BEGIN_DECLS
#define TNET_DHCP6_All_DHCP_Servers "FF05::1:3"
/*== RFC 3315 - 5.5. Transmission and Retransmission Parameters
- * This section presents a table of values used to describe the message
+ * This section presents a table of values used to describe the message
* transmission behavior of clients and servers.
*/
#define TNET_DHCP6_RT_SOL_MAX_DELAY 1 /**< 1 sec Max delay of first Solicit */
@@ -100,20 +100,19 @@ TNET_BEGIN_DECLS
/**@ingroup tnet_dhcpv_group
* DHCPv6 context.
*/
-typedef struct tnet_dhcp6_ctx_s
-{
- TSK_DECLARE_OBJECT;
-
- uint16_t pen; /**< Private Enterprise Number assigned by the IANA. Default= @ref TNET_IANA_PEN.*/
- char* vendor_class_data;
-
- uint64_t timeout;
-
- tnet_port_t port_client; /**< Local port to bind to for incloming DHCPv6 messages. Default: 546 */
- tnet_port_t server_port; /**< Destination port for outgoing DHCPv6 messages. Default: 547 */
- tnet_interfaces_L_t *interfaces;
-
- TSK_DECLARE_SAFEOBJ;
+typedef struct tnet_dhcp6_ctx_s {
+ TSK_DECLARE_OBJECT;
+
+ uint16_t pen; /**< Private Enterprise Number assigned by the IANA. Default= @ref TNET_IANA_PEN.*/
+ char* vendor_class_data;
+
+ uint64_t timeout;
+
+ tnet_port_t port_client; /**< Local port to bind to for incloming DHCPv6 messages. Default: 546 */
+ tnet_port_t server_port; /**< Destination port for outgoing DHCPv6 messages. Default: 547 */
+ tnet_interfaces_L_t *interfaces;
+
+ TSK_DECLARE_SAFEOBJ;
}
tnet_dhcp6_ctx_t;
diff --git a/tinyNET/src/dhcp6/tnet_dhcp6_duid.c b/tinyNET/src/dhcp6/tnet_dhcp6_duid.c
index 38f2a52..3bec2f4 100755
--- a/tinyNET/src/dhcp6/tnet_dhcp6_duid.c
+++ b/tinyNET/src/dhcp6/tnet_dhcp6_duid.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,101 +38,97 @@ int tnet_dhcp6_duid_ll_serialize(const tnet_dhcp6_duid_ll_t* self, tsk_buffer_t
tnet_dhcp6_duid_llt_t* tnet_dhcp6_duid_llt_create(const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp6_duid_llt_def_t, payload, payload_size);
+ return tsk_object_new(tnet_dhcp6_duid_llt_def_t, payload, payload_size);
}
tnet_dhcp6_duid_en_t* tnet_dhcp6_duid_en_create(const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp6_duid_en_def_t, payload, payload_size);
+ return tsk_object_new(tnet_dhcp6_duid_en_def_t, payload, payload_size);
}
tnet_dhcp6_duid_ll_t* tnet_dhcp6_duid_ll_create(const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp6_duid_ll_def_t, payload, payload_size);
+ return tsk_object_new(tnet_dhcp6_duid_ll_def_t, payload, payload_size);
}
int tnet_dhcp6_duid_init(tnet_dhcp6_duid_t *self, tnet_dhcp6_duid_type_t type)
{
- if(self){
- if(!self->initialized){
- self->type = type;
- self->initialized = tsk_true;
- return 0;
- }
- return -2;
- }
- return -1;
+ if(self) {
+ if(!self->initialized) {
+ self->type = type;
+ self->initialized = tsk_true;
+ return 0;
+ }
+ return -2;
+ }
+ return -1;
}
int tnet_dhcp6_duid_deinit(tnet_dhcp6_duid_t *self)
{
- if(self){
- if(self->initialized){
- self->initialized = tsk_true;
- return 0;
- }
- return -2;
- }
- return -1;
+ if(self) {
+ if(self->initialized) {
+ self->initialized = tsk_true;
+ return 0;
+ }
+ return -2;
+ }
+ return -1;
}
tnet_dhcp6_duid_t* tnet_dhcp6_duid_deserialize(const void* data, tsk_size_t size)
{
- tnet_dhcp6_duid_t *duid = 0;
- uint8_t* dataPtr = ((uint8_t*)data);
- //uint8_t* dataEnd = (dataPtr+size);
+ tnet_dhcp6_duid_t *duid = 0;
+ uint8_t* dataPtr = ((uint8_t*)data);
+ //uint8_t* dataEnd = (dataPtr+size);
- tnet_dhcp6_duid_type_t type;
- //uint8_t len = 0;
+ tnet_dhcp6_duid_type_t type;
+ //uint8_t len = 0;
- /* Check validity */
- if(!dataPtr || size<2/*Type*/){
- goto bail;
- }
+ /* Check validity */
+ if(!dataPtr || size<2/*Type*/) {
+ goto bail;
+ }
- type = (tnet_dhcp6_duid_type_t) tnet_ntohs_2(dataPtr);
- dataPtr += 2;
+ type = (tnet_dhcp6_duid_type_t) tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
bail:
- return duid;
+ return duid;
}
int tnet_dhcp6_duid_serialize(const tnet_dhcp6_duid_t* self, tsk_buffer_t *output)
{
- int ret = -1;
-
- if(!self || !output){
- return ret;
- }
-
- switch(self->type){
- case dhcp6_duid_linklayer_plus_time:
- {
- ret = tnet_dhcp6_duid_llt_serialize(TNET_DHCP6_DUID_LLT(self), output);
- break;
- }
-
- case dhcp6_duid_Vendor_assigned_id:
- {
- ret = tnet_dhcp6_duid_en_serialize(TNET_DHCP6_DUID_EN(self), output);
- break;
- }
-
- case dhcp6_duid_linklayer:
- {
- ret = tnet_dhcp6_duid_ll_serialize(TNET_DHCP6_DUID_LL(self), output);
- break;
- }
-
- default:
- {
- ret = -2;
- goto bail;
- }
- }
+ int ret = -1;
+
+ if(!self || !output) {
+ return ret;
+ }
+
+ switch(self->type) {
+ case dhcp6_duid_linklayer_plus_time: {
+ ret = tnet_dhcp6_duid_llt_serialize(TNET_DHCP6_DUID_LLT(self), output);
+ break;
+ }
+
+ case dhcp6_duid_Vendor_assigned_id: {
+ ret = tnet_dhcp6_duid_en_serialize(TNET_DHCP6_DUID_EN(self), output);
+ break;
+ }
+
+ case dhcp6_duid_linklayer: {
+ ret = tnet_dhcp6_duid_ll_serialize(TNET_DHCP6_DUID_LL(self), output);
+ break;
+ }
+
+ default: {
+ ret = -2;
+ goto bail;
+ }
+ }
bail:
- return ret;
+ return ret;
}
/*=======================================================================================
@@ -141,7 +137,7 @@ bail:
int tnet_dhcp6_duid_llt_serialize(const tnet_dhcp6_duid_llt_t* self, tsk_buffer_t *output)
{
- return -1;
+ return -1;
}
//
@@ -149,39 +145,38 @@ int tnet_dhcp6_duid_llt_serialize(const tnet_dhcp6_duid_llt_t* self, tsk_buffer_
//
static tsk_object_t* tnet_dhcp6_duid_llt_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_duid_llt_t *duid = self;
- if(duid){
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- /* init base */
- tnet_dhcp6_duid_init(TNET_DHCP6_DUID(duid), dhcp6_duid_linklayer_plus_time);
-
- if(payload && payload_size){
- /* DESERIALIZATION */
- }
- }
- return self;
+ tnet_dhcp6_duid_llt_t *duid = self;
+ if(duid) {
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ /* init base */
+ tnet_dhcp6_duid_init(TNET_DHCP6_DUID(duid), dhcp6_duid_linklayer_plus_time);
+
+ if(payload && payload_size) {
+ /* DESERIALIZATION */
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp6_duid_llt_dtor(tsk_object_t * self)
-{
- tnet_dhcp6_duid_llt_t *duid = self;
- if(duid){
- /* deinit base */
- tnet_dhcp6_duid_deinit(TNET_DHCP6_DUID(duid));
-
- TSK_OBJECT_SAFE_FREE(duid->address);
- }
- return self;
+static tsk_object_t* tnet_dhcp6_duid_llt_dtor(tsk_object_t * self)
+{
+ tnet_dhcp6_duid_llt_t *duid = self;
+ if(duid) {
+ /* deinit base */
+ tnet_dhcp6_duid_deinit(TNET_DHCP6_DUID(duid));
+
+ TSK_OBJECT_SAFE_FREE(duid->address);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_duid_llt_def_s =
-{
- sizeof(tnet_dhcp6_duid_llt_t),
- tnet_dhcp6_duid_llt_ctor,
- tnet_dhcp6_duid_llt_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp6_duid_llt_def_s = {
+ sizeof(tnet_dhcp6_duid_llt_t),
+ tnet_dhcp6_duid_llt_ctor,
+ tnet_dhcp6_duid_llt_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_duid_llt_def_t = &tnet_dhcp6_duid_llt_def_s;
@@ -192,7 +187,7 @@ const tsk_object_def_t *tnet_dhcp6_duid_llt_def_t = &tnet_dhcp6_duid_llt_def_s;
int tnet_dhcp6_duid_en_serialize(const tnet_dhcp6_duid_en_t* self, tsk_buffer_t *output)
{
- return -1;
+ return -1;
}
//
@@ -200,39 +195,38 @@ int tnet_dhcp6_duid_en_serialize(const tnet_dhcp6_duid_en_t* self, tsk_buffer_t
//
static tsk_object_t* tnet_dhcp6_duid_en_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_duid_en_t *duid = self;
- if(duid){
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- /* init base */
- tnet_dhcp6_duid_init(TNET_DHCP6_DUID(duid), dhcp6_duid_Vendor_assigned_id);
-
- if(payload && payload_size){
- /* DESERIALIZATION */
- }
- }
- return self;
+ tnet_dhcp6_duid_en_t *duid = self;
+ if(duid) {
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ /* init base */
+ tnet_dhcp6_duid_init(TNET_DHCP6_DUID(duid), dhcp6_duid_Vendor_assigned_id);
+
+ if(payload && payload_size) {
+ /* DESERIALIZATION */
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp6_duid_en_dtor(tsk_object_t * self)
-{
- tnet_dhcp6_duid_en_t *duid = self;
- if(duid){
- /* deinit base */
- tnet_dhcp6_duid_deinit(TNET_DHCP6_DUID(duid));
-
- TSK_OBJECT_SAFE_FREE(duid->indentifier);
- }
- return self;
+static tsk_object_t* tnet_dhcp6_duid_en_dtor(tsk_object_t * self)
+{
+ tnet_dhcp6_duid_en_t *duid = self;
+ if(duid) {
+ /* deinit base */
+ tnet_dhcp6_duid_deinit(TNET_DHCP6_DUID(duid));
+
+ TSK_OBJECT_SAFE_FREE(duid->indentifier);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_duid_en_def_s =
-{
- sizeof(tnet_dhcp6_duid_en_t),
- tnet_dhcp6_duid_en_ctor,
- tnet_dhcp6_duid_en_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp6_duid_en_def_s = {
+ sizeof(tnet_dhcp6_duid_en_t),
+ tnet_dhcp6_duid_en_ctor,
+ tnet_dhcp6_duid_en_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_duid_en_def_t = &tnet_dhcp6_duid_en_def_s;
@@ -243,7 +237,7 @@ const tsk_object_def_t *tnet_dhcp6_duid_en_def_t = &tnet_dhcp6_duid_en_def_s;
int tnet_dhcp6_duid_ll_serialize(const tnet_dhcp6_duid_ll_t* self, tsk_buffer_t *output)
{
- return -1;
+ return -1;
}
//
@@ -251,38 +245,37 @@ int tnet_dhcp6_duid_ll_serialize(const tnet_dhcp6_duid_ll_t* self, tsk_buffer_t
//
static tsk_object_t* tnet_dhcp6_duid_ll_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_duid_ll_t *duid = self;
- if(duid){
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- /* init base */
- tnet_dhcp6_duid_init(TNET_DHCP6_DUID(duid), dhcp6_duid_linklayer);
-
- if(payload && payload_size){
- /* DESERIALIZATION */
- }
- }
- return self;
+ tnet_dhcp6_duid_ll_t *duid = self;
+ if(duid) {
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ /* init base */
+ tnet_dhcp6_duid_init(TNET_DHCP6_DUID(duid), dhcp6_duid_linklayer);
+
+ if(payload && payload_size) {
+ /* DESERIALIZATION */
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp6_duid_ll_dtor(tsk_object_t * self)
-{
- tnet_dhcp6_duid_ll_t *duid = self;
- if(duid){
- /* deinit base */
- tnet_dhcp6_duid_deinit(TNET_DHCP6_DUID(duid));
-
- TSK_OBJECT_SAFE_FREE(duid->address);
- }
- return self;
+static tsk_object_t* tnet_dhcp6_duid_ll_dtor(tsk_object_t * self)
+{
+ tnet_dhcp6_duid_ll_t *duid = self;
+ if(duid) {
+ /* deinit base */
+ tnet_dhcp6_duid_deinit(TNET_DHCP6_DUID(duid));
+
+ TSK_OBJECT_SAFE_FREE(duid->address);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_duid_ll_def_s =
-{
- sizeof(tnet_dhcp6_duid_ll_t),
- tnet_dhcp6_duid_ll_ctor,
- tnet_dhcp6_duid_ll_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp6_duid_ll_def_s = {
+ sizeof(tnet_dhcp6_duid_ll_t),
+ tnet_dhcp6_duid_ll_ctor,
+ tnet_dhcp6_duid_ll_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_duid_ll_def_t = &tnet_dhcp6_duid_ll_def_s;
diff --git a/tinyNET/src/dhcp6/tnet_dhcp6_duid.h b/tinyNET/src/dhcp6/tnet_dhcp6_duid.h
index 34383fa..94c2b32 100755
--- a/tinyNET/src/dhcp6/tnet_dhcp6_duid.h
+++ b/tinyNET/src/dhcp6/tnet_dhcp6_duid.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -44,23 +44,21 @@ TNET_BEGIN_DECLS
/** List of DHCPv6 DUIDs types as per RFC 3315 subclause 9.1.
*/
-typedef enum tnet_dhcp6_duid_type_e
-{
- dhcp6_duid_linklayer_plus_time = 1, /**< Link-layer address plus time. */
- dhcp6_duid_Vendor_assigned_id = 2, /**< Vendor-assigned unique ID based on Enterprise Number. */
- dhcp6_duid_linklayer = 3, /**< Link-layer address. */
+typedef enum tnet_dhcp6_duid_type_e {
+ dhcp6_duid_linklayer_plus_time = 1, /**< Link-layer address plus time. */
+ dhcp6_duid_Vendor_assigned_id = 2, /**< Vendor-assigned unique ID based on Enterprise Number. */
+ dhcp6_duid_linklayer = 3, /**< Link-layer address. */
}
tnet_dhcp6_duid_type_t;
/** DHCP Unique Identifier (DUID) base class (subclause 9).
*/
-typedef struct tnet_dhcp6_duid_s
-{
- TSK_DECLARE_OBJECT;
-
- tsk_bool_t initialized;
+typedef struct tnet_dhcp6_duid_s {
+ TSK_DECLARE_OBJECT;
+
+ tsk_bool_t initialized;
- tnet_dhcp6_duid_type_t type; /* DUID type. 2-bytes value. */
+ tnet_dhcp6_duid_type_t type; /* DUID type. 2-bytes value. */
}
tnet_dhcp6_duid_t;
@@ -80,29 +78,28 @@ int tnet_dhcp6_duid_serialize(const tnet_dhcp6_duid_t* self, tsk_buffer_t *outpu
/** DUID Based on Link-layer Address Plus Time [DUID-LLT]
*/
-typedef struct tnet_dhcp6_duid_llt_s
-{
- TNET_DECLARE_DHCP6_DUID;
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | 1 | hardware type (16 bits) |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | time (32 bits) |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- . .
- . link-layer address (variable length) .
- . .
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- /* The hardware type code as maintained by IANA. */
- tnet_hardware_type_t htype;
- /* The time value is the time that the DUID is generated represented in seconds
- since midnight (UTC), January 1, 2000, modulo 2^32. */
- uint32_t time;
- /* The link-layer address. */
- tsk_buffer_t *address;
+typedef struct tnet_dhcp6_duid_llt_s {
+ TNET_DECLARE_DHCP6_DUID;
+ /*
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | 1 | hardware type (16 bits) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | time (32 bits) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ . .
+ . link-layer address (variable length) .
+ . .
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ /* The hardware type code as maintained by IANA. */
+ tnet_hardware_type_t htype;
+ /* The time value is the time that the DUID is generated represented in seconds
+ since midnight (UTC), January 1, 2000, modulo 2^32. */
+ uint32_t time;
+ /* The link-layer address. */
+ tsk_buffer_t *address;
}
tnet_dhcp6_duid_llt_t;
@@ -113,27 +110,26 @@ tnet_dhcp6_duid_llt_t;
/** DUID Assigned by Vendor Based on Enterprise Number [DUID-EN]
*/
-typedef struct tnet_dhcp6_duid_en_s
-{
- TNET_DECLARE_DHCP6_DUID;
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | 2 | enterprise-number |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | enterprise-number (contd) | |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
- . identifier .
- . (variable length) .
- . .
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- /* Tthe vendor's registered Private Enterprise Number as maintained by IANA.
- For more information: http://www.iana.org/assignments/enterprise-numbers. */
- uint32_t en;
- /* The link-layer address. */
- tsk_buffer_t *indentifier;
+typedef struct tnet_dhcp6_duid_en_s {
+ TNET_DECLARE_DHCP6_DUID;
+ /*
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | 2 | enterprise-number |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | enterprise-number (contd) | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
+ . identifier .
+ . (variable length) .
+ . .
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ /* Tthe vendor's registered Private Enterprise Number as maintained by IANA.
+ For more information: http://www.iana.org/assignments/enterprise-numbers. */
+ uint32_t en;
+ /* The link-layer address. */
+ tsk_buffer_t *indentifier;
}
tnet_dhcp6_duid_en_t;
@@ -143,11 +139,10 @@ tnet_dhcp6_duid_en_t;
/** DUID Based on Link-layer Address [DUID-LL]
*/
-typedef struct tnet_dhcp6_duid_ll_s
-{
- TNET_DECLARE_DHCP6_DUID;
- /*
- 0 1 2 3
+typedef struct tnet_dhcp6_duid_ll_s {
+ TNET_DECLARE_DHCP6_DUID;
+ /*
+ 0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 3 | hardware type (16 bits) |
@@ -156,11 +151,11 @@ typedef struct tnet_dhcp6_duid_ll_s
. link-layer address (variable length) .
. .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- /* The hardware type code as maintained by IANA. */
- tnet_hardware_type_t htype;
- /* The link-layer address. */
- tsk_buffer_t *address;
+ */
+ /* The hardware type code as maintained by IANA. */
+ tnet_hardware_type_t htype;
+ /* The link-layer address. */
+ tsk_buffer_t *address;
}
tnet_dhcp6_duid_ll_t;
diff --git a/tinyNET/src/dhcp6/tnet_dhcp6_message.c b/tinyNET/src/dhcp6/tnet_dhcp6_message.c
index 4691714..9979335 100755
--- a/tinyNET/src/dhcp6/tnet_dhcp6_message.c
+++ b/tinyNET/src/dhcp6/tnet_dhcp6_message.c
@@ -32,65 +32,64 @@
tnet_dhcp6_message_t* tnet_dhcp6_message_create(tnet_dhcp6_message_type_t type)
{
- return tsk_object_new(tnet_dhcp6_message_def_t, type);
+ return tsk_object_new(tnet_dhcp6_message_def_t, type);
}
tnet_dhcp6_request_t* tnet_dhcp6_request_create(tnet_dhcp6_message_type_t type)
{
- return tnet_dhcp6_message_create(type);
+ return tnet_dhcp6_message_create(type);
}
tsk_buffer_t* tnet_dhcp6_message_serialize(const tnet_dhcp6_ctx_t *ctx, const tnet_dhcp6_message_t *self)
{
- tsk_buffer_t* output = 0;
- //uint8_t _1byte;
- uint16_t _2bytes;
- uint32_t _4bytes;
-
- /* Check message validity */
- if (!self){
- goto bail;
- }
-
- output = tsk_buffer_create_null();
-
- /*== msg-type + transaction-id */
- _4bytes = (((uint32_t)(self->type)) << 24) | (self->transaction_id & 0xFFFFFF);
- _4bytes = tnet_ntohl(_4bytes);
- tsk_buffer_append(output, &(_4bytes), 4);
-
- /*== Vendor class
- */
- {
- _2bytes = tnet_htons(dhcp6_code_vendor_class);
- tsk_buffer_append(output, &(_2bytes), 2);
- _2bytes = tnet_htons((unsigned short)(4 + tsk_strlen(ctx->vendor_class_data)));
- tsk_buffer_append(output, &(_2bytes), 2);
- _4bytes = tnet_ntohl(ctx->pen);
- tsk_buffer_append(output, &(_4bytes), 4);
- tsk_buffer_append(output, ctx->vendor_class_data, tsk_strlen(ctx->vendor_class_data));
- }
-
- /*== DHCP Options
- */
- {
- tsk_list_item_t *item;
- tnet_dhcp6_option_t* option;
- tsk_list_foreach(item, self->options)
- {
- option = (tnet_dhcp6_option_t*)item->data;
- if (tnet_dhcp6_option_serialize(option, output)){
- TSK_DEBUG_WARN("Failed to serialize DHCPv6 OPTION (%u)", option->code);
- }
- }
- }
+ tsk_buffer_t* output = 0;
+ //uint8_t _1byte;
+ uint16_t _2bytes;
+ uint32_t _4bytes;
+
+ /* Check message validity */
+ if (!self) {
+ goto bail;
+ }
+
+ output = tsk_buffer_create_null();
+
+ /*== msg-type + transaction-id */
+ _4bytes = (((uint32_t)(self->type)) << 24) | (self->transaction_id & 0xFFFFFF);
+ _4bytes = tnet_ntohl(_4bytes);
+ tsk_buffer_append(output, &(_4bytes), 4);
+
+ /*== Vendor class
+ */
+ {
+ _2bytes = tnet_htons(dhcp6_code_vendor_class);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ _2bytes = tnet_htons((unsigned short)(4 + tsk_strlen(ctx->vendor_class_data)));
+ tsk_buffer_append(output, &(_2bytes), 2);
+ _4bytes = tnet_ntohl(ctx->pen);
+ tsk_buffer_append(output, &(_4bytes), 4);
+ tsk_buffer_append(output, ctx->vendor_class_data, tsk_strlen(ctx->vendor_class_data));
+ }
+
+ /*== DHCP Options
+ */
+ {
+ tsk_list_item_t *item;
+ tnet_dhcp6_option_t* option;
+ tsk_list_foreach(item, self->options) {
+ option = (tnet_dhcp6_option_t*)item->data;
+ if (tnet_dhcp6_option_serialize(option, output)) {
+ TSK_DEBUG_WARN("Failed to serialize DHCPv6 OPTION (%u)", option->code);
+ }
+ }
+ }
bail:
- return output;
+ return output;
}
tnet_dhcp6_message_t* tnet_dhcp6_message_deserialize(const tnet_dhcp6_ctx_t *ctx, const uint8_t *data, tsk_size_t size)
{
- return 0;
+ return 0;
}
@@ -100,32 +99,31 @@ tnet_dhcp6_message_t* tnet_dhcp6_message_deserialize(const tnet_dhcp6_ctx_t *ctx
//
static tsk_object_t* tnet_dhcp6_message_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_message_t *message = self;
- if (message){
- static uint16_t __dhcp6message_unique_tid = 0;//(uint32_t)tsk_time_epoch();
-
- message->type = va_arg(*app, tnet_dhcp6_message_type_t);
- message->transaction_id = ++__dhcp6message_unique_tid;
- message->options = tsk_list_create();
- }
- return self;
+ tnet_dhcp6_message_t *message = self;
+ if (message) {
+ static uint16_t __dhcp6message_unique_tid = 0;//(uint32_t)tsk_time_epoch();
+
+ message->type = va_arg(*app, tnet_dhcp6_message_type_t);
+ message->transaction_id = ++__dhcp6message_unique_tid;
+ message->options = tsk_list_create();
+ }
+ return self;
}
static tsk_object_t* tnet_dhcp6_message_dtor(tsk_object_t * self)
{
- tnet_dhcp6_message_t *message = self;
- if (message){
- TSK_OBJECT_SAFE_FREE(message->options);
- }
- return self;
+ tnet_dhcp6_message_t *message = self;
+ if (message) {
+ TSK_OBJECT_SAFE_FREE(message->options);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_message_def_s =
-{
- sizeof(tnet_dhcp6_message_t),
- tnet_dhcp6_message_ctor,
- tnet_dhcp6_message_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp6_message_def_s = {
+ sizeof(tnet_dhcp6_message_t),
+ tnet_dhcp6_message_ctor,
+ tnet_dhcp6_message_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_message_def_t = &tnet_dhcp6_message_def_s;
diff --git a/tinyNET/src/dhcp6/tnet_dhcp6_message.h b/tinyNET/src/dhcp6/tnet_dhcp6_message.h
index dc5d9d2..3dfd6c6 100755
--- a/tinyNET/src/dhcp6/tnet_dhcp6_message.h
+++ b/tinyNET/src/dhcp6/tnet_dhcp6_message.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -42,86 +42,84 @@ struct tnet_dhcp6_ctx_s;
/** List of all supported DHCPv6 messages.
* For more info: RFC 3315 - 5.3. DHCP Message Types
*/
-typedef enum tnet_dhcp6_message_type_e
-{
- /* A client sends a Solicit message to locate servers. */
- dhcp6_type_solicit = 1,
- /* A server sends an Advertise message to indicate that it is available for DHCP service, in
- response to a Solicit message received from a client. */
- dhcp6_type_advertise = 2,
- /* A client sends a Request message to request configuration parameters, including IP
- addresses, from a specific server. */
- dhcp6_type_request = 3,
- /* A client sends a Confirm message to any available server to determine whether the
- addresses it was assigned are still appropriate to the link to which the client is connected. */
- dhcp6_type_confirm = 4,
- /* A client sends a Renew message to the server that originally provided the client's addresses
- and configuration parameters to extend the lifetimes on the addresses assigned to the
- client and to update other configurationparameters. */
- dhcp6_type_renew = 5,
- /* A client sends a Rebind message to any available server to extend the lifetimes on the
- addresses assigned to the client and to update other configuration parameters; this message is
- sent after a client receives no response to a Renew message.*/
- dhcp6_type_rebind = 6,
- /* A server sends a Reply message containing assigned addresses and configuration parameters
- in response to a Solicit, Request, Renew, Rebind message received from a client. A
- server sends a Reply message containing configuration parameters in response to an
- Information-request message. A server sends a Reply message in response to a Confirm message
- confirming or denying that the addresses assigned to the client are appropriate to the
- link to which the client is connected. A server sends a Reply message to acknowledge
- receipt of a Release or Decline message.*/
- dhcp6_type_reply = 7,
- /* A client sends a Release message to the server that assigned addresses to the client to
- indicate that the client will no longer use one or more of the assigned addresses.*/
- dhcp6_type_release = 8,
- /* A client sends a Decline message to a server to indicate that the client has determined that
- one or more addresses assigned by the server are already in use on the link to which the
- client is connected.*/
- dhcp6_type_decline = 9,
- /*A server sends a Reconfigure message to a client to inform the client that the server has
- new or updated configuration parameters, and that the client is to initiate a Renew/Reply
- or Information-request/Reply transaction with the server in order to receive the updatedinformation. */
- dhcp6_type_reconfigure = 10,
- /* A client sends an Information-request message to a server to request configuration
- parameters without the assignment of any IP addresses to the client.*/
- dhcp6_type_information_request = 11,
- /* A relay agent sends a Relay-forward message to relay messages to servers, either directly
- or through another relay agent. The received message, either a client message or a
- Relay-forward message from another relay agent, is encapsulated in an option in the Relay-forward message.*/
- dhcp6_type_relay_forw = 12,
- /* A server sends a Relay-reply message to a relay agent containing a message that the relay
- agent delivers to a client. The Relay-reply message may be relayed by other relay agents
- for delivery to the destination relay agent.
- The server encapsulates the client message as an option in the Relay-reply message, which the
- relay agent extracts and relays to the client.*/
- dhcp6_type_relay_repl = 13,
+typedef enum tnet_dhcp6_message_type_e {
+ /* A client sends a Solicit message to locate servers. */
+ dhcp6_type_solicit = 1,
+ /* A server sends an Advertise message to indicate that it is available for DHCP service, in
+ response to a Solicit message received from a client. */
+ dhcp6_type_advertise = 2,
+ /* A client sends a Request message to request configuration parameters, including IP
+ addresses, from a specific server. */
+ dhcp6_type_request = 3,
+ /* A client sends a Confirm message to any available server to determine whether the
+ addresses it was assigned are still appropriate to the link to which the client is connected. */
+ dhcp6_type_confirm = 4,
+ /* A client sends a Renew message to the server that originally provided the client's addresses
+ and configuration parameters to extend the lifetimes on the addresses assigned to the
+ client and to update other configurationparameters. */
+ dhcp6_type_renew = 5,
+ /* A client sends a Rebind message to any available server to extend the lifetimes on the
+ addresses assigned to the client and to update other configuration parameters; this message is
+ sent after a client receives no response to a Renew message.*/
+ dhcp6_type_rebind = 6,
+ /* A server sends a Reply message containing assigned addresses and configuration parameters
+ in response to a Solicit, Request, Renew, Rebind message received from a client. A
+ server sends a Reply message containing configuration parameters in response to an
+ Information-request message. A server sends a Reply message in response to a Confirm message
+ confirming or denying that the addresses assigned to the client are appropriate to the
+ link to which the client is connected. A server sends a Reply message to acknowledge
+ receipt of a Release or Decline message.*/
+ dhcp6_type_reply = 7,
+ /* A client sends a Release message to the server that assigned addresses to the client to
+ indicate that the client will no longer use one or more of the assigned addresses.*/
+ dhcp6_type_release = 8,
+ /* A client sends a Decline message to a server to indicate that the client has determined that
+ one or more addresses assigned by the server are already in use on the link to which the
+ client is connected.*/
+ dhcp6_type_decline = 9,
+ /*A server sends a Reconfigure message to a client to inform the client that the server has
+ new or updated configuration parameters, and that the client is to initiate a Renew/Reply
+ or Information-request/Reply transaction with the server in order to receive the updatedinformation. */
+ dhcp6_type_reconfigure = 10,
+ /* A client sends an Information-request message to a server to request configuration
+ parameters without the assignment of any IP addresses to the client.*/
+ dhcp6_type_information_request = 11,
+ /* A relay agent sends a Relay-forward message to relay messages to servers, either directly
+ or through another relay agent. The received message, either a client message or a
+ Relay-forward message from another relay agent, is encapsulated in an option in the Relay-forward message.*/
+ dhcp6_type_relay_forw = 12,
+ /* A server sends a Relay-reply message to a relay agent containing a message that the relay
+ agent delivers to a client. The Relay-reply message may be relayed by other relay agents
+ for delivery to the destination relay agent.
+ The server encapsulates the client message as an option in the Relay-reply message, which the
+ relay agent extracts and relays to the client.*/
+ dhcp6_type_relay_repl = 13,
}
tnet_dhcp6_message_type_t;
/** DHCPv6 message (common fields) as per RFC 3315 subclause 6.
*/
-typedef struct tnet_dhcp6_message_s
-{
- TSK_DECLARE_OBJECT;
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | msg-type | transaction-id |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | |
- . options .
- . (variable) .
- | |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- /* Identifies the DHCP message type. 1-byte value. */
- tnet_dhcp6_message_type_t type;
- /* The transaction ID for this message exchange. 3-bytes value. */
- uint32_t transaction_id;
- /* Options carried in this message. */
- tnet_dhcp6_options_L_t *options;
+typedef struct tnet_dhcp6_message_s {
+ TSK_DECLARE_OBJECT;
+ /*
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | msg-type | transaction-id |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | |
+ . options .
+ . (variable) .
+ | |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ /* Identifies the DHCP message type. 1-byte value. */
+ tnet_dhcp6_message_type_t type;
+ /* The transaction ID for this message exchange. 3-bytes value. */
+ uint32_t transaction_id;
+ /* Options carried in this message. */
+ tnet_dhcp6_options_L_t *options;
}
tnet_dhcp6_message_t;
diff --git a/tinyNET/src/dhcp6/tnet_dhcp6_option.c b/tinyNET/src/dhcp6/tnet_dhcp6_option.c
index 91ec16a..58107c6 100755
--- a/tinyNET/src/dhcp6/tnet_dhcp6_option.c
+++ b/tinyNET/src/dhcp6/tnet_dhcp6_option.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -37,125 +37,120 @@
tnet_dhcp6_option_t* tnet_dhcp6_option_create(tnet_dhcp6_option_code_t code, const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp6_option_def_t, code, payload, payload_size);
+ return tsk_object_new(tnet_dhcp6_option_def_t, code, payload, payload_size);
}
tnet_dhcp6_option_identifier_t* tnet_dhcp6_option_indentifer_create(tnet_dhcp6_option_code_t code, const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp6_option_identifier_def_t, code, payload, payload_size);
+ return tsk_object_new(tnet_dhcp6_option_identifier_def_t, code, payload, payload_size);
}
tnet_dhcp6_option_identifier_t* tnet_dhcp6_option_clientid_create(const void* payload, tsk_size_t payload_size)
{
- return tnet_dhcp6_option_indentifer_create(dhcp6_code_clientid, payload, payload_size);
+ return tnet_dhcp6_option_indentifer_create(dhcp6_code_clientid, payload, payload_size);
}
tnet_dhcp6_option_identifier_t* tnet_dhcp6_option_serverid_create(const void* payload, tsk_size_t payload_size)
{
- return tnet_dhcp6_option_indentifer_create(dhcp6_code_serverid, payload, payload_size);
+ return tnet_dhcp6_option_indentifer_create(dhcp6_code_serverid, payload, payload_size);
}
tnet_dhcp6_option_orequest_t* tnet_dhcp6_option_orequest_create(const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp6_option_orequest_def_t, payload, payload_size);
+ return tsk_object_new(tnet_dhcp6_option_orequest_def_t, payload, payload_size);
}
tnet_dhcp6_option_orequest_t* tnet_dhcp6_option_orequest_create_null()
{
- return tnet_dhcp6_option_orequest_create(tsk_null, 0);
+ return tnet_dhcp6_option_orequest_create(tsk_null, 0);
}
tnet_dhcp6_option_vendorclass_t* tnet_dhcp6_option_vendorclass_create(const void* payload, tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dhcp6_option_vendorclass_def_t, payload, payload_size);
+ return tsk_object_new(tnet_dhcp6_option_vendorclass_def_t, payload, payload_size);
}
tnet_dhcp6_option_vendorclass_t* tnet_dhcp6_option_vendorclass_create_null()
{
- return tnet_dhcp6_option_vendorclass_create(tsk_null, 0);
+ return tnet_dhcp6_option_vendorclass_create(tsk_null, 0);
}
tnet_dhcp6_option_t* tnet_dhcp6_option_deserialize(const void* data, tsk_size_t size)
{
- tnet_dhcp6_option_t *option = 0;
- uint8_t* dataPtr = ((uint8_t*)data);
- //uint8_t* dataEnd = (dataPtr+size);
-
- tnet_dhcp6_option_code_t code;
- uint16_t len;
-
- /* Check validity */
- if(!dataPtr || size<4/*Code Len*/){
- goto bail;
- }
-
- code = (tnet_dhcp6_option_code_t) tnet_ntohs_2(dataPtr);
- dataPtr += 2;
-
- len = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
-
- switch(code){
- case dhcp6_code_clientid:
- case dhcp6_code_serverid:
- {
- break;
- }
-
- default:
- {
- break;
- }
- }
+ tnet_dhcp6_option_t *option = 0;
+ uint8_t* dataPtr = ((uint8_t*)data);
+ //uint8_t* dataEnd = (dataPtr+size);
+
+ tnet_dhcp6_option_code_t code;
+ uint16_t len;
+
+ /* Check validity */
+ if(!dataPtr || size<4/*Code Len*/) {
+ goto bail;
+ }
+
+ code = (tnet_dhcp6_option_code_t) tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+
+ len = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+
+ switch(code) {
+ case dhcp6_code_clientid:
+ case dhcp6_code_serverid: {
+ break;
+ }
+
+ default: {
+ break;
+ }
+ }
bail:
- return option;
+ return option;
}
int tnet_dhcp6_option_serialize(const tnet_dhcp6_option_t* self, tsk_buffer_t *output)
{
- uint16_t _2bytes;
- int ret = -1;
-
- if(!self || !output){
- goto bail;
- }
-
- /*== Code */
- _2bytes = tnet_htons(self->code);
- tsk_buffer_append(output, &(_2bytes), 2);
-
- switch(self->code){
- case dhcp6_code_clientid:
- case dhcp6_code_serverid:
- {
- break;
- }
-
- case dhcp6_code_oro:
- default:
- {
- if(self->data)
- {
- const tnet_dhcp6_option_orequest_t* opt = (const tnet_dhcp6_option_orequest_t*)self->data;
- if(opt->codes){
- /* option-len */
- _2bytes = tnet_htons((unsigned short)opt->codes->size);
- tsk_buffer_append(output, &(_2bytes), 2);
- /* option-data */
- ret = tsk_buffer_append(output, opt->codes->data, opt->codes->size);
- }
-
- }
- break;
- }
- }
+ uint16_t _2bytes;
+ int ret = -1;
+
+ if(!self || !output) {
+ goto bail;
+ }
+
+ /*== Code */
+ _2bytes = tnet_htons(self->code);
+ tsk_buffer_append(output, &(_2bytes), 2);
+
+ switch(self->code) {
+ case dhcp6_code_clientid:
+ case dhcp6_code_serverid: {
+ break;
+ }
+
+ case dhcp6_code_oro:
+ default: {
+ if(self->data) {
+ const tnet_dhcp6_option_orequest_t* opt = (const tnet_dhcp6_option_orequest_t*)self->data;
+ if(opt->codes) {
+ /* option-len */
+ _2bytes = tnet_htons((unsigned short)opt->codes->size);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /* option-data */
+ ret = tsk_buffer_append(output, opt->codes->data, opt->codes->size);
+ }
+
+ }
+ break;
+ }
+ }
bail:
- return ret;
+ return ret;
}
int tnet_dhcp6_option_serializeex(tnet_dhcp6_option_code_t code, uint8_t length, const void* value, tsk_buffer_t *output)
{
- return -1;
+ return -1;
}
//
@@ -163,43 +158,42 @@ int tnet_dhcp6_option_serializeex(tnet_dhcp6_option_code_t code, uint8_t length,
//
static tsk_object_t* tnet_dhcp6_option_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_option_t *option = self;
- if(option){
- tnet_dhcp6_option_code_t code = va_arg(*app, tnet_dhcp6_option_code_t);
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- option->code = code;
- if(payload && payload_size){
- if((option->data = (tnet_dhcp6_option_data_t*)tsk_calloc(payload_size, sizeof(uint8_t)))){
- memcpy(option->data, payload, payload_size);
- option->len = (uint16_t)payload_size;
- }
- }
- }
- return self;
+ tnet_dhcp6_option_t *option = self;
+ if(option) {
+ tnet_dhcp6_option_code_t code = va_arg(*app, tnet_dhcp6_option_code_t);
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ option->code = code;
+ if(payload && payload_size) {
+ if((option->data = (tnet_dhcp6_option_data_t*)tsk_calloc(payload_size, sizeof(uint8_t)))) {
+ memcpy(option->data, payload, payload_size);
+ option->len = (uint16_t)payload_size;
+ }
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp6_option_dtor(tsk_object_t * self)
-{
- tnet_dhcp6_option_t *option = self;
- if(option){
- TSK_OBJECT_SAFE_FREE(option->data);
- }
- return self;
+static tsk_object_t* tnet_dhcp6_option_dtor(tsk_object_t * self)
+{
+ tnet_dhcp6_option_t *option = self;
+ if(option) {
+ TSK_OBJECT_SAFE_FREE(option->data);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_option_def_s =
-{
- sizeof(tnet_dhcp6_option_t),
- tnet_dhcp6_option_ctor,
- tnet_dhcp6_option_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp6_option_def_s = {
+ sizeof(tnet_dhcp6_option_t),
+ tnet_dhcp6_option_ctor,
+ tnet_dhcp6_option_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_option_def_t = &tnet_dhcp6_option_def_s;
/*======================================================================================
-* RFC 3315 -
+* RFC 3315 -
22.2. Client Identifier Option
22.3. Server Identifier Option
*=======================================================================================*/
@@ -208,34 +202,33 @@ const tsk_object_def_t *tnet_dhcp6_option_def_t = &tnet_dhcp6_option_def_s;
//
static tsk_object_t* tnet_dhcp6_option_identifier_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_option_identifier_t *option = self;
- if(option){
- //tnet_dhcp6_option_code_t code = va_arg(*app, tnet_dhcp6_option_code_t);
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- if(payload && payload_size){
- /* DESERIALIZATION */
- }
- }
- return self;
+ tnet_dhcp6_option_identifier_t *option = self;
+ if(option) {
+ //tnet_dhcp6_option_code_t code = va_arg(*app, tnet_dhcp6_option_code_t);
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ if(payload && payload_size) {
+ /* DESERIALIZATION */
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp6_option_identifier_dtor(tsk_object_t * self)
-{
- tnet_dhcp6_option_identifier_t *option = self;
- if(option){
- TSK_OBJECT_SAFE_FREE(option->duid);
- }
- return self;
+static tsk_object_t* tnet_dhcp6_option_identifier_dtor(tsk_object_t * self)
+{
+ tnet_dhcp6_option_identifier_t *option = self;
+ if(option) {
+ TSK_OBJECT_SAFE_FREE(option->duid);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_option_identifier_def_s =
-{
- sizeof(tnet_dhcp6_option_identifier_t),
- tnet_dhcp6_option_identifier_ctor,
- tnet_dhcp6_option_identifier_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp6_option_identifier_def_s = {
+ sizeof(tnet_dhcp6_option_identifier_t),
+ tnet_dhcp6_option_identifier_ctor,
+ tnet_dhcp6_option_identifier_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_option_identifier_def_t = &tnet_dhcp6_option_identifier_def_s;
@@ -245,20 +238,20 @@ const tsk_object_def_t *tnet_dhcp6_option_identifier_def_t = &tnet_dhcp6_option_
int tnet_dhcp6_option_orequest_add_code(tnet_dhcp6_option_orequest_t* self, uint16_t code)
{
- uint16_t _2bytes;
- int ret = -1;
- if(self){
- if(!self->codes){
- if(!(self->codes = tsk_buffer_create_null())){
- return -3;
- }
- }
- _2bytes = tnet_ntohs(code);
- if(!(ret = tsk_buffer_append(self->codes, &_2bytes, 2))){
- TNET_DHCP6_OPTION(self)->len += 2;
- }
- }
- return ret;
+ uint16_t _2bytes;
+ int ret = -1;
+ if(self) {
+ if(!self->codes) {
+ if(!(self->codes = tsk_buffer_create_null())) {
+ return -3;
+ }
+ }
+ _2bytes = tnet_ntohs(code);
+ if(!(ret = tsk_buffer_append(self->codes, &_2bytes, 2))) {
+ TNET_DHCP6_OPTION(self)->len += 2;
+ }
+ }
+ return ret;
}
//
@@ -266,33 +259,32 @@ int tnet_dhcp6_option_orequest_add_code(tnet_dhcp6_option_orequest_t* self, uint
//
static tsk_object_t* tnet_dhcp6_option_orequest_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_option_orequest_t *option = self;
- if(option){
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- if(payload && payload_size)
- { /* DESERIALIZATION */
- }
- }
- return self;
+ tnet_dhcp6_option_orequest_t *option = self;
+ if(option) {
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ if(payload && payload_size) {
+ /* DESERIALIZATION */
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp6_option_orequest_dtor(tsk_object_t * self)
-{
- tnet_dhcp6_option_orequest_t *option = self;
- if(option){
- TSK_OBJECT_SAFE_FREE(option->codes);
- }
- return self;
+static tsk_object_t* tnet_dhcp6_option_orequest_dtor(tsk_object_t * self)
+{
+ tnet_dhcp6_option_orequest_t *option = self;
+ if(option) {
+ TSK_OBJECT_SAFE_FREE(option->codes);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_option_orequest_def_s =
-{
- sizeof(tnet_dhcp6_option_orequest_t),
- tnet_dhcp6_option_orequest_ctor,
- tnet_dhcp6_option_orequest_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp6_option_orequest_def_s = {
+ sizeof(tnet_dhcp6_option_orequest_t),
+ tnet_dhcp6_option_orequest_ctor,
+ tnet_dhcp6_option_orequest_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_option_orequest_def_t = &tnet_dhcp6_option_orequest_def_s;
@@ -305,32 +297,31 @@ const tsk_object_def_t *tnet_dhcp6_option_orequest_def_t = &tnet_dhcp6_option_or
//
static tsk_object_t* tnet_dhcp6_option_vendorclass_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dhcp6_option_vendorclass_t *option = self;
- if(option){
- const void* payload = va_arg(*app, const void*);
- tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-
- if(payload && payload_size){
- /* DESERIALIZATION */
- }
- }
- return self;
+ tnet_dhcp6_option_vendorclass_t *option = self;
+ if(option) {
+ const void* payload = va_arg(*app, const void*);
+ tsk_size_t payload_size = va_arg(*app, tsk_size_t);
+
+ if(payload && payload_size) {
+ /* DESERIALIZATION */
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dhcp6_option_vendorclass_dtor(tsk_object_t * self)
-{
- tnet_dhcp6_option_vendorclass_t *option = self;
- if(option){
- TSK_OBJECT_SAFE_FREE(option->vendor_class_data);
- }
- return self;
+static tsk_object_t* tnet_dhcp6_option_vendorclass_dtor(tsk_object_t * self)
+{
+ tnet_dhcp6_option_vendorclass_t *option = self;
+ if(option) {
+ TSK_OBJECT_SAFE_FREE(option->vendor_class_data);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dhcp6_option_vendorclass_def_s =
-{
- sizeof(tnet_dhcp6_option_vendorclass_t),
- tnet_dhcp6_option_vendorclass_ctor,
- tnet_dhcp6_option_vendorclass_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dhcp6_option_vendorclass_def_s = {
+ sizeof(tnet_dhcp6_option_vendorclass_t),
+ tnet_dhcp6_option_vendorclass_ctor,
+ tnet_dhcp6_option_vendorclass_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dhcp6_option_vendorclass_def_t = &tnet_dhcp6_option_vendorclass_def_s;
diff --git a/tinyNET/src/dhcp6/tnet_dhcp6_option.h b/tinyNET/src/dhcp6/tnet_dhcp6_option.h
index 71241b9..56ec83e 100755
--- a/tinyNET/src/dhcp6/tnet_dhcp6_option.h
+++ b/tinyNET/src/dhcp6/tnet_dhcp6_option.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -42,47 +42,45 @@ TNET_BEGIN_DECLS
#define TNET_DHCP6_OPTION(self) ((tnet_dhcp6_option_t*)(self))
/** List of DHCPv6 option as registered by IANA (RFC 3315 subcaluse 24.3)*/
-typedef enum tnet_dhcp6_option_code_e
-{
- dhcp6_code_clientid = 1, /**< Client Identifier Option. */
- dhcp6_code_serverid = 2, /**< Server Identifier Option. */
- dhcp6_code_ia_na = 3, /**< Identity Association for Non-temporary Addresses Option. */
- dhcp6_code_ia_ta = 4, /**< Identity Association for Temporary Addresses Option. */
- dhcp6_code_iaaddr = 5, /**< IA Address Option. */
- dhcp6_code_oro = 6, /**< Option Request Option. */
- dhcp6_code_preference = 7, /**< Preference Option. */
- dhcp6_code_elapsed_time = 8, /**< Elapsed Time Option. */
- dhcp6_code_relay_msg = 9, /**< Relay Message Option. */
- dhcp6_code_auth = 11, /**< Authentication Option. */
- dhcp6_code_unicast = 12, /**< Server Unicast Option. */
- dhcp6_code_status_code = 13, /**< Status Code Option. */
- dhcp6_code_rapid_commit = 14, /**< Rapid Commit Option. */
- dhcp6_code_user_class = 15, /**< User Class Option. */
- dhcp6_code_vendor_class = 16, /**< Vendor Class Option. */
- dhcp6_code_vendor_opts = 17, /**< Vendor-specific Information Option. */
- dhcp6_code_interface_id = 18, /**< Interface-Id Option. */
- dhcp6_code_reconf_msg = 19, /**< Reconfigure Message Option. */
- dhcp6_code_reconf_accept = 20, /**< Reconfigure Accept Option. */
+typedef enum tnet_dhcp6_option_code_e {
+ dhcp6_code_clientid = 1, /**< Client Identifier Option. */
+ dhcp6_code_serverid = 2, /**< Server Identifier Option. */
+ dhcp6_code_ia_na = 3, /**< Identity Association for Non-temporary Addresses Option. */
+ dhcp6_code_ia_ta = 4, /**< Identity Association for Temporary Addresses Option. */
+ dhcp6_code_iaaddr = 5, /**< IA Address Option. */
+ dhcp6_code_oro = 6, /**< Option Request Option. */
+ dhcp6_code_preference = 7, /**< Preference Option. */
+ dhcp6_code_elapsed_time = 8, /**< Elapsed Time Option. */
+ dhcp6_code_relay_msg = 9, /**< Relay Message Option. */
+ dhcp6_code_auth = 11, /**< Authentication Option. */
+ dhcp6_code_unicast = 12, /**< Server Unicast Option. */
+ dhcp6_code_status_code = 13, /**< Status Code Option. */
+ dhcp6_code_rapid_commit = 14, /**< Rapid Commit Option. */
+ dhcp6_code_user_class = 15, /**< User Class Option. */
+ dhcp6_code_vendor_class = 16, /**< Vendor Class Option. */
+ dhcp6_code_vendor_opts = 17, /**< Vendor-specific Information Option. */
+ dhcp6_code_interface_id = 18, /**< Interface-Id Option. */
+ dhcp6_code_reconf_msg = 19, /**< Reconfigure Message Option. */
+ dhcp6_code_reconf_accept = 20, /**< Reconfigure Accept Option. */
}
tnet_dhcp6_option_code_t;
/** List of DHCPv6 status codes as registered by IANA (RFC 3315 subclause 24.4) */
-typedef enum tnet_dhcp6_statuscode_e
-{
- /* Success */
- dhcp6_statuscode_Success = 0,
- /* Failure, reason unspecified; this status code is sent by either a client
- or a server to indicate a failure not explicitly specified in this document (RFC 3315). */
- dhcp6_statuscode_UnspecFail = 1,
- /* Server has no addresses available to assign to the IA(s). */
- dhcp6_statuscode_NoAddrsAvail = 2,
- /* Client record (binding) unavailable. */
- dhcp6_statuscode_NoBinding = 3,
- /* The prefix for the address is not appropriate for the link to which the client is attached. */
- dhcp6_statuscode_NotOnLink = 4,
- /* Sent by a server to a client to force the client to send messages to the server.
- using the All_DHCP_Relay_Agents_and_Servers address.*/
- dhcp6_statuscode_UseMulticast = 5
+typedef enum tnet_dhcp6_statuscode_e {
+ /* Success */
+ dhcp6_statuscode_Success = 0,
+ /* Failure, reason unspecified; this status code is sent by either a client
+ or a server to indicate a failure not explicitly specified in this document (RFC 3315). */
+ dhcp6_statuscode_UnspecFail = 1,
+ /* Server has no addresses available to assign to the IA(s). */
+ dhcp6_statuscode_NoAddrsAvail = 2,
+ /* Client record (binding) unavailable. */
+ dhcp6_statuscode_NoBinding = 3,
+ /* The prefix for the address is not appropriate for the link to which the client is attached. */
+ dhcp6_statuscode_NotOnLink = 4,
+ /* Sent by a server to a client to force the client to send messages to the server.
+ using the All_DHCP_Relay_Agents_and_Servers address.*/
+ dhcp6_statuscode_UseMulticast = 5
}
tnet_dhcp6_statuscode_t;
@@ -93,34 +91,32 @@ tnet_dhcp6_statuscode_t;
/**@ingroup tnet_dhcpv_group
* DHCPv6 option-data.
*/
-typedef struct tnet_dhcp6_option_data_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_dhcp6_option_data_s {
+ TSK_DECLARE_OBJECT;
}
tnet_dhcp6_option_data_t;
#define TNET_DECLARE_DHCP6_OPTION_DATA tnet_dhcp6_option_data_t dhcp6_option_data
-typedef struct tnet_dhcp6_option_s
-{
- TSK_DECLARE_OBJECT;
-
- /* RFC 3315 - 22.1. Format of DHCP Options
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | option-code(2) | option-len(2) |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | option-data |
- | (option-len octets) |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
- /* An unsigned integer identifying the specific option type carried in this option.*/
- tnet_dhcp6_option_code_t code;
- /* Option length. Same as tsk_strlen(data buffer)*/
- uint16_t len;
- /* opton-data */
- tnet_dhcp6_option_data_t *data;
+typedef struct tnet_dhcp6_option_s {
+ TSK_DECLARE_OBJECT;
+
+ /* RFC 3315 - 22.1. Format of DHCP Options
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | option-code(2) | option-len(2) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | option-data |
+ | (option-len octets) |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+ /* An unsigned integer identifying the specific option type carried in this option.*/
+ tnet_dhcp6_option_code_t code;
+ /* Option length. Same as tsk_strlen(data buffer)*/
+ uint16_t len;
+ /* opton-data */
+ tnet_dhcp6_option_data_t *data;
}
tnet_dhcp6_option_t;
@@ -136,29 +132,28 @@ int tnet_dhcp6_option_serializeex(tnet_dhcp6_option_code_t code, uint8_t length,
/*======================================================================================
-* RFC 3315 -
+* RFC 3315 -
22.2. Client Identifier Option
22.3. Server Identifier Option
*=======================================================================================*/
/** DHCPv6 Client /server Identifier Option (subclause 22.2 and 22.3).
*/
-typedef struct tnet_dhcp6_option_identifier_s
-{
- TNET_DECLARE_DHCP6_OPTION_DATA;
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | OPTION_XXXXXXID | option-len |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- . .
- . DUID .
- . (variable length) .
- . .
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- OPTION_XXXXXXID = OPTION_CLIENTID or OPTION_SERVERID
- */
- tnet_dhcp6_duid_t *duid;
+typedef struct tnet_dhcp6_option_identifier_s {
+ TNET_DECLARE_DHCP6_OPTION_DATA;
+ /*
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | OPTION_XXXXXXID | option-len |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ . .
+ . DUID .
+ . (variable length) .
+ . .
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ OPTION_XXXXXXID = OPTION_CLIENTID or OPTION_SERVERID
+ */
+ tnet_dhcp6_duid_t *duid;
}
tnet_dhcp6_option_identifier_t;
typedef tnet_dhcp6_option_identifier_t tnet_dhcp6_option_clientid_t;
@@ -175,21 +170,20 @@ typedef tnet_dhcp6_option_identifier_t tnet_dhcp6_option_serverid_t;
/** DHCPv6 Option Request Option (subclause 22.7).
*/
-typedef struct tnet_dhcp6_option_orequest_s
-{
- TNET_DECLARE_DHCP6_OPTION_DATA;
- /*
- 0 1 2 3
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | OPTION_ORO | option-len |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | requested-option-code-1 | requested-option-code-2 |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- | ... |
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- tsk_buffer_t* codes;
+typedef struct tnet_dhcp6_option_orequest_s {
+ TNET_DECLARE_DHCP6_OPTION_DATA;
+ /*
+ 0 1 2 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | OPTION_ORO | option-len |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | requested-option-code-1 | requested-option-code-2 |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | ... |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ tsk_buffer_t* codes;
}
tnet_dhcp6_option_orequest_t;
@@ -201,11 +195,10 @@ TINYNET_API int tnet_dhcp6_option_orequest_add_code(tnet_dhcp6_option_orequest_t
/** DHCPv6 Vendor Class Option (subclause 22.16).
*/
-typedef struct tnet_dhcp6_option_vendorclass_s
-{
- TNET_DECLARE_DHCP6_OPTION_DATA;
- /*
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+typedef struct tnet_dhcp6_option_vendorclass_s {
+ TNET_DECLARE_DHCP6_OPTION_DATA;
+ /*
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| OPTION_VENDOR_CLASS | option-len |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -215,14 +208,14 @@ typedef struct tnet_dhcp6_option_vendorclass_s
. vendor-class-data .
. . . . .
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
- uint32_t enterprise_number;
- /*
- +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+
+ */
+ uint32_t enterprise_number;
+ /*
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+
| vendor-class-len | opaque-data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-...-+-+-+-+-+-+-+
- */
- tsk_buffer_t* vendor_class_data;
+ */
+ tsk_buffer_t* vendor_class_data;
}
tnet_dhcp6_option_vendorclass_t;
diff --git a/tinyNET/src/dns/tnet_dns.c b/tinyNET/src/dns/tnet_dns.c
index 87cd9b5..e131c4d 100755
--- a/tinyNET/src/dns/tnet_dns.c
+++ b/tinyNET/src/dns/tnet_dns.c
@@ -158,7 +158,7 @@ TSK_OBJECT_SAFE_FREE(ctx);
*/
tnet_dns_ctx_t* tnet_dns_ctx_create()
{
- return tsk_object_new(tnet_dns_ctx_def_t);
+ return tsk_object_new(tnet_dns_ctx_def_t);
}
/**@ingroup tnet_dns_group
@@ -166,7 +166,7 @@ tnet_dns_ctx_t* tnet_dns_ctx_create()
*/
tnet_dns_cache_entry_t* tnet_dns_cache_entry_create(const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype, tnet_dns_response_t* answer)
{
- return tsk_object_new(tnet_dns_cache_entry_def_t, qname, qclass, qtype, answer);
+ return tsk_object_new(tnet_dns_cache_entry_def_t, qname, qclass, qtype, answer);
}
@@ -178,14 +178,14 @@ tnet_dns_cache_entry_t* tnet_dns_cache_entry_create(const char* qname, tnet_dns_
*/
int tnet_dns_cache_clear(tnet_dns_ctx_t* ctx)
{
- if (ctx){
- tsk_safeobj_lock(ctx);
- tsk_list_clear_items(ctx->cache);
- tsk_safeobj_unlock(ctx);
-
- return 0;
- }
- return -1;
+ if (ctx) {
+ tsk_safeobj_lock(ctx);
+ tsk_list_clear_items(ctx->cache);
+ tsk_safeobj_unlock(ctx);
+
+ return 0;
+ }
+ return -1;
}
/**@ingroup tnet_dns_group
@@ -208,274 +208,275 @@ int tnet_dns_cache_clear(tnet_dns_ctx_t* ctx)
tnet_dns_response_t *tnet_dns_resolve(tnet_dns_ctx_t* ctx, const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype)
{
#if HAVE_DNS_H
- struct sockaddr_storage result;
- struct sockaddr *from;
- uint32_t fromlen;
- char buf[TNET_DNS_DGRAM_SIZE_DEFAULT];
- int32_t ret;
-
- tnet_dns_response_t *response = tsk_null;
-
- tnet_socket_t *localsocket4 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv4);
- tnet_socket_t *localsocket6 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv6);
-
- tsk_safeobj_lock(ctx);
-
- // First, try with IPv4
- if(TNET_SOCKET_IS_VALID(localsocket4)){
- if((ret = tnet_getsockname(localsocket4->fd, &result))){
- TNET_PRINT_LAST_ERROR("tnet_getsockname() failed.");
- goto ipv6;
- }
- from = (struct sockaddr *) &result;
- fromlen = tnet_get_sockaddr_size(from);
-
- if ((ret = dns_search(ctx->resolv_handle, qname, qclass, qtype, buf, TNET_DNS_DGRAM_SIZE_DEFAULT, from, &fromlen)) > 0) {
- response = tnet_dns_message_deserialize((uint8_t *) buf, ret);
- goto done;
- }
- else{
- TNET_PRINT_LAST_ERROR("dns_search_v4()");
- }
- }
+ struct sockaddr_storage result;
+ struct sockaddr *from;
+ uint32_t fromlen;
+ char buf[TNET_DNS_DGRAM_SIZE_DEFAULT];
+ int32_t ret;
+
+ tnet_dns_response_t *response = tsk_null;
+
+ tnet_socket_t *localsocket4 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv4);
+ tnet_socket_t *localsocket6 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv6);
+
+ tsk_safeobj_lock(ctx);
+
+ // First, try with IPv4
+ if(TNET_SOCKET_IS_VALID(localsocket4)) {
+ if((ret = tnet_getsockname(localsocket4->fd, &result))) {
+ TNET_PRINT_LAST_ERROR("tnet_getsockname() failed.");
+ goto ipv6;
+ }
+ from = (struct sockaddr *) &result;
+ fromlen = tnet_get_sockaddr_size(from);
+
+ if ((ret = dns_search(ctx->resolv_handle, qname, qclass, qtype, buf, TNET_DNS_DGRAM_SIZE_DEFAULT, from, &fromlen)) > 0) {
+ response = tnet_dns_message_deserialize((uint8_t *) buf, ret);
+ goto done;
+ }
+ else {
+ TNET_PRINT_LAST_ERROR("dns_search_v4()");
+ }
+ }
ipv6:
- // Then, try with IPv6
- if(TNET_SOCKET_IS_VALID(localsocket6)){
- if((ret = tnet_getsockname(localsocket6->fd, &result))){
- TNET_PRINT_LAST_ERROR("tnet_getsockname() failed.");
- goto done;
- }
- from = (struct sockaddr *) &result;
- fromlen = tnet_get_sockaddr_size(from);
-
- if((ret = dns_search(ctx->resolv_handle, qname, qclass, qtype, buf, TNET_DNS_DGRAM_SIZE_DEFAULT, from, &fromlen)) > 0){
- response = tnet_dns_message_deserialize((uint8_t *) buf, ret);
- goto done;
- }
- else{
- TNET_PRINT_LAST_ERROR("dns_search_v6()");
- }
- }
+ // Then, try with IPv6
+ if(TNET_SOCKET_IS_VALID(localsocket6)) {
+ if((ret = tnet_getsockname(localsocket6->fd, &result))) {
+ TNET_PRINT_LAST_ERROR("tnet_getsockname() failed.");
+ goto done;
+ }
+ from = (struct sockaddr *) &result;
+ fromlen = tnet_get_sockaddr_size(from);
+
+ if((ret = dns_search(ctx->resolv_handle, qname, qclass, qtype, buf, TNET_DNS_DGRAM_SIZE_DEFAULT, from, &fromlen)) > 0) {
+ response = tnet_dns_message_deserialize((uint8_t *) buf, ret);
+ goto done;
+ }
+ else {
+ TNET_PRINT_LAST_ERROR("dns_search_v6()");
+ }
+ }
done:
- tsk_safeobj_unlock(ctx);
+ tsk_safeobj_unlock(ctx);
- TSK_OBJECT_SAFE_FREE(localsocket4);
- TSK_OBJECT_SAFE_FREE(localsocket6);
+ TSK_OBJECT_SAFE_FREE(localsocket4);
+ TSK_OBJECT_SAFE_FREE(localsocket6);
- return response;
+ return response;
#else
- tsk_buffer_t *output = tsk_null;
- tnet_dns_query_t* query = tnet_dns_query_create(qname, qclass, qtype);
- tnet_dns_response_t *response = tsk_null;
- tsk_bool_t from_cache = tsk_false;
-
- /* Check validity */
- if (!ctx || !query){
- goto bail;
- }
-
- /* Is there any DNS Server? */
- if (TSK_LIST_IS_EMPTY(ctx->servers)){
- TSK_DEBUG_ERROR("Failed to load DNS Servers. You can add new DNS servers by using \"tnet_dns_add_server\".");
- goto bail;
- }
-
- /* Cache maintenance */
- if (!TSK_LIST_IS_EMPTY(ctx->cache)){
- /* Only do maintenance if the cache is not empty */
- tnet_dns_cache_maintenance(ctx);
- }
-
- /* Retrieve data from cache. */
- if (ctx->caching){
- const tnet_dns_cache_entry_t *entry = tnet_dns_cache_entry_get(ctx, qname, qclass, qtype);
- if (entry){
- response = tsk_object_ref(((tnet_dns_cache_entry_t*)entry)->response);
- from_cache = tsk_true;
- goto bail;
- }
- }
-
- /* Set user preference */
- query->Header.RD = ctx->recursion;
-
- /* EDNS0 */
- if (ctx->edns0){
- tnet_dns_opt_t *rr_opt = tnet_dns_opt_create(TNET_DNS_DGRAM_SIZE_DEFAULT);
- if (!query->Additionals){
- query->Additionals = tsk_list_create();
- }
- tsk_list_push_back_data(query->Additionals, (void**)&rr_opt);
- query->Header.ARCOUNT++;
- }
-
- /* Serialize and send to the server. */
- if (!(output = tnet_dns_message_serialize(query))){
- TSK_DEBUG_ERROR("Failed to serialize the DNS message.");
- goto bail;
- }
-
- /* ============================ */
- // Send and Recaive data
- /* ============================ */
- {
- int ret = -1;
- struct timeval tv;
- fd_set set;
- tnet_fd_t maxFD;
- uint64_t timeout = 0;
- tsk_list_item_t *item;
- const tnet_address_t *address;
- struct sockaddr_storage server;
- tnet_socket_t *localsocket4 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv4);
- tnet_socket_t *localsocket6 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv6);
- tsk_bool_t useIPv6 = TNET_SOCKET_IS_VALID(localsocket6);
-
- tsk_safeobj_lock(ctx);
-
- /* Check socket validity */
- if (!TNET_SOCKET_IS_VALID(localsocket4)){
- goto done;
- }
-
- /* Always wait 500ms before retransmission */
- tv.tv_sec = 0;
- tv.tv_usec = (500 * 1000);
-
- do
- {
- //
- // Send data (loop through all intefaces)
- //
- tsk_list_foreach(item, ctx->servers)
- {
- address = item->data;
- if (!address->ip ||
- (address->family != AF_INET && address->family != AF_INET6) ||
- (address->family == AF_INET6 && !TNET_SOCKET_IS_VALID(localsocket6))){
- continue;
- }
-
- if (tnet_sockaddr_init(address->ip, ctx->server_port, (address->family == AF_INET ? tnet_socket_type_udp_ipv4 : tnet_socket_type_udp_ipv6), &server)){
- TSK_DEBUG_ERROR("Failed to initialize the DNS server address: \"%s\"", address->ip);
- continue;
- }
-
- TSK_DEBUG_INFO("Sending DNS query to \"%s\"", address->ip);
-
- if (address->family == AF_INET6){
- if ((ret = tnet_sockfd_sendto(localsocket6->fd, (const struct sockaddr*)&server, output->data, output->size))){
- // succeed?
- break;
- }
- }
- else{
- if ((ret = tnet_sockfd_sendto(localsocket4->fd, (const struct sockaddr*)&server, output->data, output->size))){
- // succeed?
- break;
- }
- }
- }
-
- //
- // Received data
- //
- /* First time? ==> set timeout value */
- if (!timeout){
- timeout = tsk_time_epoch() + ctx->timeout;
- }
-
- /* Set FDs */
- FD_ZERO(&set);
- FD_SET(localsocket4->fd, &set);
- if (useIPv6){
- FD_SET(localsocket6->fd, &set);
- maxFD = TSK_MAX(localsocket4->fd, localsocket6->fd);
- }
- else{
- maxFD = localsocket4->fd;
- }
-
- /* wait for response */
- if ((ret = select(maxFD + 1, &set, NULL, NULL, &tv)) < 0){ /* Error */
- TNET_PRINT_LAST_ERROR("Select failed.");
- goto done;
- }
- else if (ret == 0){ /* timeout ==> do nothing */
-
- }
- else{ /* there is data to read */
- unsigned int len = 0;
- void* data = 0;
- tnet_fd_t active_fd;
-
- /* Find active file descriptor */
- if (FD_ISSET(localsocket4->fd, &set)){
- active_fd = localsocket4->fd;
- }
- else if (FD_ISSET(localsocket6->fd, &set)){
- active_fd = localsocket4->fd;
- }
- else{
- TSK_DEBUG_ERROR("FD_ISSET ==> Invalid file descriptor.");
- continue;
- }
-
- /* Check how how many bytes are pending */
- if ((ret = tnet_ioctlt(active_fd, FIONREAD, &len)) < 0){
- TSK_DEBUG_ERROR("tnet_ioctlt failed with error code:%d", tnet_geterrno());
- goto done;
- }
-
- /* Receive pending data */
- data = tsk_calloc(len, sizeof(uint8_t));
- if ((ret = tnet_sockfd_recv(active_fd, data, len, 0)) < 0){
- TSK_FREE(data);
-
- TSK_DEBUG_ERROR("tnet_sockfd_recv failed with error code:%d", tnet_geterrno());
- goto done;
- }
-
- /* Parse the incoming response. */
- response = tnet_dns_message_deserialize(data, (tsk_size_t)ret);
- TSK_FREE(data);
-
- if (response)
- { /* response successfuly parsed */
- if (query->Header.ID != response->Header.ID || !TNET_DNS_MESSAGE_IS_RESPONSE(response)){
- /* Not same transaction id ==> continue*/
- TSK_OBJECT_SAFE_FREE(response);
- }
- else goto done;
- }
- }
- } while (timeout > tsk_time_epoch());
-
- done:
- tsk_safeobj_unlock(ctx);
-
- TSK_OBJECT_SAFE_FREE(localsocket4);
- TSK_OBJECT_SAFE_FREE(localsocket6);
- goto bail;
- }
+ tsk_buffer_t *output = tsk_null;
+ tnet_dns_query_t* query = tnet_dns_query_create(qname, qclass, qtype);
+ tnet_dns_response_t *response = tsk_null;
+ tsk_bool_t from_cache = tsk_false;
+
+ /* Check validity */
+ if (!ctx || !query) {
+ goto bail;
+ }
+
+ /* Is there any DNS Server? */
+ if (TSK_LIST_IS_EMPTY(ctx->servers)) {
+ TSK_DEBUG_ERROR("Failed to load DNS Servers. You can add new DNS servers by using \"tnet_dns_add_server\".");
+ goto bail;
+ }
+
+ /* Cache maintenance */
+ if (!TSK_LIST_IS_EMPTY(ctx->cache)) {
+ /* Only do maintenance if the cache is not empty */
+ tnet_dns_cache_maintenance(ctx);
+ }
+
+ /* Retrieve data from cache. */
+ if (ctx->caching) {
+ const tnet_dns_cache_entry_t *entry = tnet_dns_cache_entry_get(ctx, qname, qclass, qtype);
+ if (entry) {
+ response = tsk_object_ref(((tnet_dns_cache_entry_t*)entry)->response);
+ from_cache = tsk_true;
+ goto bail;
+ }
+ }
+
+ /* Set user preference */
+ query->Header.RD = ctx->recursion;
+
+ /* EDNS0 */
+ if (ctx->edns0) {
+ tnet_dns_opt_t *rr_opt = tnet_dns_opt_create(TNET_DNS_DGRAM_SIZE_DEFAULT);
+ if (!query->Additionals) {
+ query->Additionals = tsk_list_create();
+ }
+ tsk_list_push_back_data(query->Additionals, (void**)&rr_opt);
+ query->Header.ARCOUNT++;
+ }
+
+ /* Serialize and send to the server. */
+ if (!(output = tnet_dns_message_serialize(query))) {
+ TSK_DEBUG_ERROR("Failed to serialize the DNS message.");
+ goto bail;
+ }
+
+ /* ============================ */
+ // Send and Recaive data
+ /* ============================ */
+ {
+ int ret = -1;
+ struct timeval tv;
+ fd_set set;
+ tnet_fd_t maxFD;
+ uint64_t timeout = 0;
+ tsk_list_item_t *item;
+ const tnet_address_t *address;
+ struct sockaddr_storage server;
+ tnet_socket_t *localsocket4 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv4);
+ tnet_socket_t *localsocket6 = tnet_socket_create(TNET_SOCKET_HOST_ANY, TNET_SOCKET_PORT_ANY, tnet_socket_type_udp_ipv6);
+ tsk_bool_t useIPv6 = TNET_SOCKET_IS_VALID(localsocket6);
+
+ tsk_safeobj_lock(ctx);
+
+ /* Check socket validity */
+ if (!TNET_SOCKET_IS_VALID(localsocket4)) {
+ goto done;
+ }
+
+ /* Always wait 500ms before retransmission */
+ tv.tv_sec = 0;
+ tv.tv_usec = (500 * 1000);
+
+ do {
+ //
+ // Send data (loop through all intefaces)
+ //
+ tsk_list_foreach(item, ctx->servers) {
+ address = item->data;
+ if (!address->ip ||
+ (address->family != AF_INET && address->family != AF_INET6) ||
+ (address->family == AF_INET6 && !TNET_SOCKET_IS_VALID(localsocket6))) {
+ continue;
+ }
+
+ if (tnet_sockaddr_init(address->ip, ctx->server_port, (address->family == AF_INET ? tnet_socket_type_udp_ipv4 : tnet_socket_type_udp_ipv6), &server)) {
+ TSK_DEBUG_ERROR("Failed to initialize the DNS server address: \"%s\"", address->ip);
+ continue;
+ }
+
+ TSK_DEBUG_INFO("Sending DNS query to \"%s\"", address->ip);
+
+ if (address->family == AF_INET6) {
+ if ((ret = tnet_sockfd_sendto(localsocket6->fd, (const struct sockaddr*)&server, output->data, output->size))) {
+ // succeed?
+ break;
+ }
+ }
+ else {
+ if ((ret = tnet_sockfd_sendto(localsocket4->fd, (const struct sockaddr*)&server, output->data, output->size))) {
+ // succeed?
+ break;
+ }
+ }
+ }
+
+ //
+ // Received data
+ //
+ /* First time? ==> set timeout value */
+ if (!timeout) {
+ timeout = tsk_time_epoch() + ctx->timeout;
+ }
+
+ /* Set FDs */
+ FD_ZERO(&set);
+ FD_SET(localsocket4->fd, &set);
+ if (useIPv6) {
+ FD_SET(localsocket6->fd, &set);
+ maxFD = TSK_MAX(localsocket4->fd, localsocket6->fd);
+ }
+ else {
+ maxFD = localsocket4->fd;
+ }
+
+ /* wait for response */
+ if ((ret = select(maxFD + 1, &set, NULL, NULL, &tv)) < 0) { /* Error */
+ TNET_PRINT_LAST_ERROR("Select failed.");
+ goto done;
+ }
+ else if (ret == 0) { /* timeout ==> do nothing */
+
+ }
+ else { /* there is data to read */
+ unsigned int len = 0;
+ void* data = 0;
+ tnet_fd_t active_fd;
+
+ /* Find active file descriptor */
+ if (FD_ISSET(localsocket4->fd, &set)) {
+ active_fd = localsocket4->fd;
+ }
+ else if (FD_ISSET(localsocket6->fd, &set)) {
+ active_fd = localsocket4->fd;
+ }
+ else {
+ TSK_DEBUG_ERROR("FD_ISSET ==> Invalid file descriptor.");
+ continue;
+ }
+
+ /* Check how how many bytes are pending */
+ if ((ret = tnet_ioctlt(active_fd, FIONREAD, &len)) < 0) {
+ TSK_DEBUG_ERROR("tnet_ioctlt failed with error code:%d", tnet_geterrno());
+ goto done;
+ }
+
+ /* Receive pending data */
+ data = tsk_calloc(len, sizeof(uint8_t));
+ if ((ret = tnet_sockfd_recv(active_fd, data, len, 0)) < 0) {
+ TSK_FREE(data);
+
+ TSK_DEBUG_ERROR("tnet_sockfd_recv failed with error code:%d", tnet_geterrno());
+ goto done;
+ }
+
+ /* Parse the incoming response. */
+ response = tnet_dns_message_deserialize(data, (tsk_size_t)ret);
+ TSK_FREE(data);
+
+ if (response) {
+ /* response successfuly parsed */
+ if (query->Header.ID != response->Header.ID || !TNET_DNS_MESSAGE_IS_RESPONSE(response)) {
+ /* Not same transaction id ==> continue*/
+ TSK_OBJECT_SAFE_FREE(response);
+ }
+ else {
+ goto done;
+ }
+ }
+ }
+ }
+ while (timeout > tsk_time_epoch());
+
+done:
+ tsk_safeobj_unlock(ctx);
+
+ TSK_OBJECT_SAFE_FREE(localsocket4);
+ TSK_OBJECT_SAFE_FREE(localsocket6);
+ goto bail;
+ }
bail:
- TSK_OBJECT_SAFE_FREE(query);
- TSK_OBJECT_SAFE_FREE(output);
-
- /* Add the result to the cache. */
- if (response){
- if (!from_cache && ctx->caching){
- tnet_dns_cache_entry_add(ctx, qname, qclass, qtype, response);
- }
- }
- else{
- TSK_DEBUG_ERROR("Failed to contact the DNS server.");
- }
-
- return response;
+ TSK_OBJECT_SAFE_FREE(query);
+ TSK_OBJECT_SAFE_FREE(output);
+
+ /* Add the result to the cache. */
+ if (response) {
+ if (!from_cache && ctx->caching) {
+ tnet_dns_cache_entry_add(ctx, qname, qclass, qtype, response);
+ }
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to contact the DNS server.");
+ }
+
+ return response;
#endif
}
@@ -491,65 +492,65 @@ bail:
*/
tnet_dns_response_t* tnet_dns_enum(tnet_dns_ctx_t* ctx, const char* e164num, const char* domain)
{
- char e164domain[255];
- tnet_dns_response_t* ret = tsk_null;
- int e164size;
- int i, j; // must be signed
-
- e164size = (int)tsk_strlen(e164num);
-
- if (!ctx || !e164num || !e164size){
- goto bail;
- }
-
- if (e164size /* max=15 digits + ".e164.arpa" + '+' */ >= (sizeof(e164domain) - 1)){
- TSK_DEBUG_ERROR("%s is an invalid E.164 number.", e164num);
- goto bail;
- }
-
- memset(e164domain, '\0', sizeof(e164domain));
-
- /* RFC 3761 - 2.4. Valid Databases
- 1. Remove all characters with the exception of the digits. For
- example, the First Well Known Rule produced the Key
- "+442079460148". This step would simply remove the leading "+",
- producing "442079460148".
-
- 2. Put dots (".") between each digit. Example:
- 4.4.2.0.7.9.4.6.0.1.4.8
-
- 3. Reverse the order of the digits. Example:
- 8.4.1.0.6.4.9.7.0.2.4.4
-
- 4. Append the string ".e164.arpa" to the end. Example:
- 8.4.1.0.6.4.9.7.0.2.4.4.e164.arpa
-
- This domain-name is used to request NAPTR records which may contain
- the end result or, if the flags field is blank, produces new keys in
- the form of domain-names from the DNS.
- */
- for (i = e164size - 1, j = 0; i >= 0; i--){
- if (!isdigit(e164num[i])){
- continue;
- }
- e164domain[j++] = e164num[i];
- e164domain[j++] = '.';
- }
-
- // append domain name
- if (domain){
- memcpy(&e164domain[j], domain, ((tsk_strlen(domain) + j) >= sizeof(e164domain) - 1) ? (sizeof(e164domain) - j - 1) : tsk_strlen(domain));
- }
- else{
- memcpy(&e164domain[j], "e164.arpa", 9);
- }
-
- /* == Performs DNS (NAPTR) lookup == */
- ret = tnet_dns_resolve(ctx, e164domain, qclass_in, qtype_naptr);
+ char e164domain[255];
+ tnet_dns_response_t* ret = tsk_null;
+ int e164size;
+ int i, j; // must be signed
+
+ e164size = (int)tsk_strlen(e164num);
+
+ if (!ctx || !e164num || !e164size) {
+ goto bail;
+ }
+
+ if (e164size /* max=15 digits + ".e164.arpa" + '+' */ >= (sizeof(e164domain) - 1)) {
+ TSK_DEBUG_ERROR("%s is an invalid E.164 number.", e164num);
+ goto bail;
+ }
+
+ memset(e164domain, '\0', sizeof(e164domain));
+
+ /* RFC 3761 - 2.4. Valid Databases
+ 1. Remove all characters with the exception of the digits. For
+ example, the First Well Known Rule produced the Key
+ "+442079460148". This step would simply remove the leading "+",
+ producing "442079460148".
+
+ 2. Put dots (".") between each digit. Example:
+ 4.4.2.0.7.9.4.6.0.1.4.8
+
+ 3. Reverse the order of the digits. Example:
+ 8.4.1.0.6.4.9.7.0.2.4.4
+
+ 4. Append the string ".e164.arpa" to the end. Example:
+ 8.4.1.0.6.4.9.7.0.2.4.4.e164.arpa
+
+ This domain-name is used to request NAPTR records which may contain
+ the end result or, if the flags field is blank, produces new keys in
+ the form of domain-names from the DNS.
+ */
+ for (i = e164size - 1, j = 0; i >= 0; i--) {
+ if (!isdigit(e164num[i])) {
+ continue;
+ }
+ e164domain[j++] = e164num[i];
+ e164domain[j++] = '.';
+ }
+
+ // append domain name
+ if (domain) {
+ memcpy(&e164domain[j], domain, ((tsk_strlen(domain) + j) >= sizeof(e164domain) - 1) ? (sizeof(e164domain) - j - 1) : tsk_strlen(domain));
+ }
+ else {
+ memcpy(&e164domain[j], "e164.arpa", 9);
+ }
+
+ /* == Performs DNS (NAPTR) lookup == */
+ ret = tnet_dns_resolve(ctx, e164domain, qclass_in, qtype_naptr);
bail:
- return ret;
+ return ret;
}
/**@ingroup tnet_dns_group
@@ -568,48 +569,48 @@ bail:
*/
char* tnet_dns_enum_2(tnet_dns_ctx_t* ctx, const char* service, const char* e164num, const char* domain)
{
- tnet_dns_response_t* response;
- const tsk_list_item_t* item;
- char* ret = tsk_null;
- const tnet_dns_rr_t* rr;
-
- if ((response = tnet_dns_enum(ctx, e164num, domain))){
- if (TNET_DNS_RESPONSE_IS_SUCCESS(response)){
- tsk_list_foreach(item, response->Answers){
- rr = item->data;
- if (rr->qtype == qtype_naptr){
- const tnet_dns_naptr_t *naptr = (const tnet_dns_naptr_t*)rr;
- /* RFC 3403 - 6.2 E164 Example
- Both the ENUM [18] and URI Resolution [4] Applications use the 'u'
- flag. This flag states that the Rule is terminal and that the output
- is a URI which contains the information needed to contact that
- telephone service.
- */
- if (tsk_striequals(naptr->flags, "u") && tsk_striequals(naptr->services, service)){
- /* RFC 3403 - 4.1 Packet Format
- The fields (replacement and regexp) are also mutually exclusive. If a record is
- returned that has values for both fields then it is considered to
- be in error and SHOULD be either ignored or an error returned.
- */
- if (naptr->regexp && naptr->replacement){
- continue;
- }
-
- if ((ret = tnet_dns_regex_parse(e164num, naptr->regexp))){
- break;
- }
- }
- }
- }
- }
- else{
- TSK_DEBUG_ERROR("We got an error response from the DNS server. Error code: %u", response->Header.RCODE);
- }
-
- TSK_OBJECT_SAFE_FREE(response);
- }
-
- return ret;
+ tnet_dns_response_t* response;
+ const tsk_list_item_t* item;
+ char* ret = tsk_null;
+ const tnet_dns_rr_t* rr;
+
+ if ((response = tnet_dns_enum(ctx, e164num, domain))) {
+ if (TNET_DNS_RESPONSE_IS_SUCCESS(response)) {
+ tsk_list_foreach(item, response->Answers) {
+ rr = item->data;
+ if (rr->qtype == qtype_naptr) {
+ const tnet_dns_naptr_t *naptr = (const tnet_dns_naptr_t*)rr;
+ /* RFC 3403 - 6.2 E164 Example
+ Both the ENUM [18] and URI Resolution [4] Applications use the 'u'
+ flag. This flag states that the Rule is terminal and that the output
+ is a URI which contains the information needed to contact that
+ telephone service.
+ */
+ if (tsk_striequals(naptr->flags, "u") && tsk_striequals(naptr->services, service)) {
+ /* RFC 3403 - 4.1 Packet Format
+ The fields (replacement and regexp) are also mutually exclusive. If a record is
+ returned that has values for both fields then it is considered to
+ be in error and SHOULD be either ignored or an error returned.
+ */
+ if (naptr->regexp && naptr->replacement) {
+ continue;
+ }
+
+ if ((ret = tnet_dns_regex_parse(e164num, naptr->regexp))) {
+ break;
+ }
+ }
+ }
+ }
+ }
+ else {
+ TSK_DEBUG_ERROR("We got an error response from the DNS server. Error code: %u", response->Header.RCODE);
+ }
+
+ TSK_OBJECT_SAFE_FREE(response);
+ }
+
+ return ret;
}
/**@ingroup tnet_dns_group
@@ -637,33 +638,31 @@ char* tnet_dns_enum_2(tnet_dns_ctx_t* ctx, const char* service, const char* e164
*/
int tnet_dns_query_srv(tnet_dns_ctx_t *ctx, const char* service, char** hostname, tnet_port_t* port)
{
- tnet_dns_response_t *response;
-
- if (!ctx){
- return -1;
- }
-
- // tnet_dns_resolve is thread-safe
- if ((response = tnet_dns_resolve(ctx, service, qclass_in, qtype_srv)))
- {
- const tsk_list_item_t *item;
- const tnet_dns_rr_t* rr;
- tsk_list_foreach(item, response->Answers) /* Already Filtered ==> Peek the first One */
- {
- rr = item->data;
- if (rr->qtype == qtype_srv){
- const tnet_dns_srv_t *srv = (const tnet_dns_srv_t*)rr;
-
- tsk_strupdate(hostname, srv->target);
- *port = srv->port;
- break;
- }
- }
- }
-
- TSK_OBJECT_SAFE_FREE(response);
-
- return (hostname && !tsk_strnullORempty(*hostname)) ? 0 : -2;
+ tnet_dns_response_t *response;
+
+ if (!ctx) {
+ return -1;
+ }
+
+ // tnet_dns_resolve is thread-safe
+ if ((response = tnet_dns_resolve(ctx, service, qclass_in, qtype_srv))) {
+ const tsk_list_item_t *item;
+ const tnet_dns_rr_t* rr;
+ tsk_list_foreach(item, response->Answers) { /* Already Filtered ==> Peek the first One */
+ rr = item->data;
+ if (rr->qtype == qtype_srv) {
+ const tnet_dns_srv_t *srv = (const tnet_dns_srv_t*)rr;
+
+ tsk_strupdate(hostname, srv->target);
+ *port = srv->port;
+ break;
+ }
+ }
+ }
+
+ TSK_OBJECT_SAFE_FREE(response);
+
+ return (hostname && !tsk_strnullORempty(*hostname)) ? 0 : -2;
}
/**@ingroup tnet_dns_group
@@ -692,157 +691,152 @@ int tnet_dns_query_srv(tnet_dns_ctx_t *ctx, const char* service, char** hostname
*/
int tnet_dns_query_naptr_srv(tnet_dns_ctx_t *ctx, const char* domain, const char* service, char** hostname, tnet_port_t* port)
{
- tnet_dns_response_t *response;
-
- if (!ctx || !hostname){
- TSK_DEBUG_ERROR("Invalid parameters.");
- return -1;
- }
-
- /* reset (do not free the user supplied value). trying to free dummy value will cause access violation error ==> zero. */
- *hostname = tsk_null;
-
- // tnet_dns_resolve is thread-safe
- if ((response = tnet_dns_resolve(ctx, domain, qclass_in, qtype_naptr))){
- const tsk_list_item_t *item;
- const tnet_dns_rr_t* rr;
-
- char* replacement = tsk_null; /* e.g. _sip._udp.example.com */
- char* flags = tsk_null;/* e.g. S, A, AAAA, A6, U, P ... */
-
- tsk_list_foreach(item, response->Answers) /* Already Filtered ==> Peek the first One */
- {
- rr = item->data;
- if (rr->qtype == qtype_naptr){
- tnet_dns_naptr_t *naptr = (tnet_dns_naptr_t*)rr;
-
- if (tsk_striequals(service, naptr->services)){
- tsk_strupdate(&replacement, naptr->replacement);
- tsk_strupdate(&flags, naptr->flags);
-
- break;
- }
- }
- }
-
- if (flags && replacement){
- if (tsk_striequals(flags, "S")){
- tnet_dns_query_srv(ctx, replacement, hostname, port);
- }
- else if (tsk_striequals(flags, "A") || tsk_striequals(flags, "AAAA") || tsk_striequals(flags, "A6")){
- TSK_DEBUG_WARN("Defaulting port value.");
- tsk_strupdate(hostname, replacement);
- *port = 5060;
- }
- else{
- TSK_DEBUG_ERROR("DNS NAPTR query returned invalid flags");
- }
- }
- else{
- TSK_DEBUG_INFO("DNS NAPTR (%s) query returned zero result", domain);
- }
-
- TSK_FREE(flags);
- TSK_FREE(replacement);
- }
-
- TSK_OBJECT_SAFE_FREE(response);
-
- return (hostname && *hostname && !tsk_strempty(*hostname)) ? 0 : -2;
+ tnet_dns_response_t *response;
+
+ if (!ctx || !hostname) {
+ TSK_DEBUG_ERROR("Invalid parameters.");
+ return -1;
+ }
+
+ /* reset (do not free the user supplied value). trying to free dummy value will cause access violation error ==> zero. */
+ *hostname = tsk_null;
+
+ // tnet_dns_resolve is thread-safe
+ if ((response = tnet_dns_resolve(ctx, domain, qclass_in, qtype_naptr))) {
+ const tsk_list_item_t *item;
+ const tnet_dns_rr_t* rr;
+
+ char* replacement = tsk_null; /* e.g. _sip._udp.example.com */
+ char* flags = tsk_null;/* e.g. S, A, AAAA, A6, U, P ... */
+
+ tsk_list_foreach(item, response->Answers) { /* Already Filtered ==> Peek the first One */
+ rr = item->data;
+ if (rr->qtype == qtype_naptr) {
+ tnet_dns_naptr_t *naptr = (tnet_dns_naptr_t*)rr;
+
+ if (tsk_striequals(service, naptr->services)) {
+ tsk_strupdate(&replacement, naptr->replacement);
+ tsk_strupdate(&flags, naptr->flags);
+
+ break;
+ }
+ }
+ }
+
+ if (flags && replacement) {
+ if (tsk_striequals(flags, "S")) {
+ tnet_dns_query_srv(ctx, replacement, hostname, port);
+ }
+ else if (tsk_striequals(flags, "A") || tsk_striequals(flags, "AAAA") || tsk_striequals(flags, "A6")) {
+ TSK_DEBUG_WARN("Defaulting port value.");
+ tsk_strupdate(hostname, replacement);
+ *port = 5060;
+ }
+ else {
+ TSK_DEBUG_ERROR("DNS NAPTR query returned invalid flags");
+ }
+ }
+ else {
+ TSK_DEBUG_INFO("DNS NAPTR (%s) query returned zero result", domain);
+ }
+
+ TSK_FREE(flags);
+ TSK_FREE(replacement);
+ }
+
+ TSK_OBJECT_SAFE_FREE(response);
+
+ return (hostname && *hostname && !tsk_strempty(*hostname)) ? 0 : -2;
}
// remove timedout entries
int tnet_dns_cache_maintenance(tnet_dns_ctx_t *ctx)
{
- if (ctx)
- {
- tsk_list_item_t *item;
- tsk_safeobj_lock(ctx);
- again:
-
- tsk_list_foreach(item, ctx->cache)
- {
- // FIXME: ttl should be from RR::ttl
- tnet_dns_cache_entry_t *entry = (tnet_dns_cache_entry_t*)item->data;
- if ((entry->epoch + ctx->cache_ttl) < tsk_time_epoch()){
- tsk_list_remove_item_by_data(ctx->cache, entry);
- goto again; /* Do not delete data while looping */
- }
- }
-
- tsk_safeobj_unlock(ctx);
-
- return 0;
- }
- return -1;
+ if (ctx) {
+ tsk_list_item_t *item;
+ tsk_safeobj_lock(ctx);
+again:
+
+ tsk_list_foreach(item, ctx->cache) {
+ // FIXME: ttl should be from RR::ttl
+ tnet_dns_cache_entry_t *entry = (tnet_dns_cache_entry_t*)item->data;
+ if ((entry->epoch + ctx->cache_ttl) < tsk_time_epoch()) {
+ tsk_list_remove_item_by_data(ctx->cache, entry);
+ goto again; /* Do not delete data while looping */
+ }
+ }
+
+ tsk_safeobj_unlock(ctx);
+
+ return 0;
+ }
+ return -1;
}
// add an entry to the cache
int tnet_dns_cache_entry_add(tnet_dns_ctx_t *ctx, const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype, tnet_dns_response_t* response)
{
- int ret = -1;
-
- if (ctx)
- {
- tnet_dns_cache_entry_t *entry;
-
- tsk_safeobj_lock(ctx);
-
- entry = 0;
-
- /* Retrieve from cache */
- entry = (tnet_dns_cache_entry_t*)tnet_dns_cache_entry_get(ctx, qname, qclass, qtype);
-
- if (entry){
- /* UPDATE */
- TSK_OBJECT_SAFE_FREE(entry->response);
- entry->response = tsk_object_ref(response);
- entry->epoch = tsk_time_epoch();
- ret = 0;
- goto done;
- }
- else{
- /* CREATE */
- entry = tnet_dns_cache_entry_create(qname, qclass, qtype, response);
- if (entry){
- tsk_list_push_back_data(ctx->cache, (void**)&entry);
- ret = 0;
- goto done;
- }
- else{
- ret = -2;
- goto done;
- }
- }
- done:
- tsk_safeobj_unlock(ctx);
- }
- return ret;
+ int ret = -1;
+
+ if (ctx) {
+ tnet_dns_cache_entry_t *entry;
+
+ tsk_safeobj_lock(ctx);
+
+ entry = 0;
+
+ /* Retrieve from cache */
+ entry = (tnet_dns_cache_entry_t*)tnet_dns_cache_entry_get(ctx, qname, qclass, qtype);
+
+ if (entry) {
+ /* UPDATE */
+ TSK_OBJECT_SAFE_FREE(entry->response);
+ entry->response = tsk_object_ref(response);
+ entry->epoch = tsk_time_epoch();
+ ret = 0;
+ goto done;
+ }
+ else {
+ /* CREATE */
+ entry = tnet_dns_cache_entry_create(qname, qclass, qtype, response);
+ if (entry) {
+ tsk_list_push_back_data(ctx->cache, (void**)&entry);
+ ret = 0;
+ goto done;
+ }
+ else {
+ ret = -2;
+ goto done;
+ }
+ }
+done:
+ tsk_safeobj_unlock(ctx);
+ }
+ return ret;
}
// get an entry from the cache
const tnet_dns_cache_entry_t* tnet_dns_cache_entry_get(tnet_dns_ctx_t *ctx, const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype)
{
- tnet_dns_cache_entry_t *ret = tsk_null;
- if (ctx)
- {
- tsk_list_item_t *item;
+ tnet_dns_cache_entry_t *ret = tsk_null;
+ if (ctx) {
+ tsk_list_item_t *item;
- tsk_safeobj_lock(ctx);
+ tsk_safeobj_lock(ctx);
- tsk_list_foreach(item, ctx->cache){
- tnet_dns_cache_entry_t *entry = (tnet_dns_cache_entry_t*)item->data;
- if (entry->qtype == qtype && entry->qclass == qclass && tsk_strequals(entry->qname, qname)){
- ret = entry;
- break;
- }
- }
+ tsk_list_foreach(item, ctx->cache) {
+ tnet_dns_cache_entry_t *entry = (tnet_dns_cache_entry_t*)item->data;
+ if (entry->qtype == qtype && entry->qclass == qclass && tsk_strequals(entry->qname, qname)) {
+ ret = entry;
+ break;
+ }
+ }
- tsk_safeobj_unlock(ctx);
- }
+ tsk_safeobj_unlock(ctx);
+ }
- return ret;
+ return ret;
}
@@ -854,25 +848,25 @@ const tnet_dns_cache_entry_t* tnet_dns_cache_entry_get(tnet_dns_ctx_t *ctx, cons
*/
int tnet_dns_add_server(tnet_dns_ctx_t *ctx, const char* host)
{
- tnet_address_t *address;
+ tnet_address_t *address;
- if (!ctx || !host){
- return -1;
- }
+ if (!ctx || !host) {
+ return -1;
+ }
- if (!ctx->servers){
- ctx->servers = tsk_list_create();
- }
+ if (!ctx->servers) {
+ ctx->servers = tsk_list_create();
+ }
- if ((address = tnet_address_create(host))){
- address->family = tnet_get_family(host, TNET_DNS_SERVER_PORT_DEFAULT);
- address->dnsserver = 1;
- tsk_list_push_ascending_data(ctx->servers, (void**)&address);
+ if ((address = tnet_address_create(host))) {
+ address->family = tnet_get_family(host, TNET_DNS_SERVER_PORT_DEFAULT);
+ address->dnsserver = 1;
+ tsk_list_push_ascending_data(ctx->servers, (void**)&address);
- return 0;
- }
+ return 0;
+ }
- return -2;
+ return -2;
}
//=================================================================================================
@@ -880,33 +874,32 @@ int tnet_dns_add_server(tnet_dns_ctx_t *ctx, const char* host)
//
static tsk_object_t* tnet_dns_cache_entry_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_cache_entry_t *entry = self;
- if (entry){
- entry->qname = tsk_strdup(va_arg(*app, const char*));
- entry->qclass = va_arg(*app, tnet_dns_qclass_t);
- entry->qtype = va_arg(*app, tnet_dns_qtype_t);
- entry->response = tsk_object_ref(va_arg(*app, tnet_dns_response_t*));
-
- entry->epoch = tsk_time_epoch();
- }
- return self;
+ tnet_dns_cache_entry_t *entry = self;
+ if (entry) {
+ entry->qname = tsk_strdup(va_arg(*app, const char*));
+ entry->qclass = va_arg(*app, tnet_dns_qclass_t);
+ entry->qtype = va_arg(*app, tnet_dns_qtype_t);
+ entry->response = tsk_object_ref(va_arg(*app, tnet_dns_response_t*));
+
+ entry->epoch = tsk_time_epoch();
+ }
+ return self;
}
static tsk_object_t* tnet_dns_cache_entry_dtor(tsk_object_t * self)
{
- tnet_dns_cache_entry_t *entry = self;
- if (entry){
- TSK_OBJECT_SAFE_FREE(entry->response);
- }
- return self;
+ tnet_dns_cache_entry_t *entry = self;
+ if (entry) {
+ TSK_OBJECT_SAFE_FREE(entry->response);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_cache_entry_def_s =
-{
- sizeof(tnet_dns_cache_entry_t),
- tnet_dns_cache_entry_ctor,
- tnet_dns_cache_entry_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_cache_entry_def_s = {
+ sizeof(tnet_dns_cache_entry_t),
+ tnet_dns_cache_entry_ctor,
+ tnet_dns_cache_entry_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_cache_entry_def_t = &tnet_dns_cache_entry_def_s;
@@ -916,52 +909,51 @@ const tsk_object_def_t *tnet_dns_cache_entry_def_t = &tnet_dns_cache_entry_def_s
//
static tsk_object_t* tnet_dns_ctx_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_ctx_t *ctx = self;
- if (ctx){
- ctx->timeout = TNET_DNS_TIMEOUT_DEFAULT;
- ctx->recursion = tsk_true;
- ctx->edns0 = tsk_true;
- ctx->caching = tsk_false;
+ tnet_dns_ctx_t *ctx = self;
+ if (ctx) {
+ ctx->timeout = TNET_DNS_TIMEOUT_DEFAULT;
+ ctx->recursion = tsk_true;
+ ctx->edns0 = tsk_true;
+ ctx->caching = tsk_false;
- ctx->cache_ttl = TNET_DNS_CACHE_TTL;
+ ctx->cache_ttl = TNET_DNS_CACHE_TTL;
- ctx->server_port = TNET_DNS_SERVER_PORT_DEFAULT;
+ ctx->server_port = TNET_DNS_SERVER_PORT_DEFAULT;
- /* Gets all dns servers. */
- ctx->servers = tnet_get_addresses_all_dnsservers();
- /* Creates empty cache. */
- ctx->cache = tsk_list_create();
+ /* Gets all dns servers. */
+ ctx->servers = tnet_get_addresses_all_dnsservers();
+ /* Creates empty cache. */
+ ctx->cache = tsk_list_create();
#if HAVE_DNS_H
- ctx->resolv_handle = dns_open(NULL);
+ ctx->resolv_handle = dns_open(NULL);
#endif
- tsk_safeobj_init(ctx);
- }
- return self;
- }
+ tsk_safeobj_init(ctx);
+ }
+ return self;
+}
static tsk_object_t* tnet_dns_ctx_dtor(tsk_object_t * self)
{
- tnet_dns_ctx_t *ctx = self;
- if (ctx){
- tsk_safeobj_deinit(ctx);
+ tnet_dns_ctx_t *ctx = self;
+ if (ctx) {
+ tsk_safeobj_deinit(ctx);
- TSK_OBJECT_SAFE_FREE(ctx->servers);
- TSK_OBJECT_SAFE_FREE(ctx->cache);
+ TSK_OBJECT_SAFE_FREE(ctx->servers);
+ TSK_OBJECT_SAFE_FREE(ctx->cache);
#if HAVE_DNS_H
- dns_free(ctx->resolv_handle);
+ dns_free(ctx->resolv_handle);
#endif
- }
- return self;
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_ctx_def_s =
-{
- sizeof(tnet_dns_ctx_t),
- tnet_dns_ctx_ctor,
- tnet_dns_ctx_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_ctx_def_s = {
+ sizeof(tnet_dns_ctx_t),
+ tnet_dns_ctx_ctor,
+ tnet_dns_ctx_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_ctx_def_t = &tnet_dns_ctx_def_s;
diff --git a/tinyNET/src/dns/tnet_dns.h b/tinyNET/src/dns/tnet_dns.h
index d4c2e6d..6d17356 100755
--- a/tinyNET/src/dns/tnet_dns.h
+++ b/tinyNET/src/dns/tnet_dns.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -49,12 +49,12 @@ TNET_BEGIN_DECLS
#define TNET_DNS_CACHE_TTL (15000 * 1000)
/**@ingroup tnet_dns_group
-* Default timeout (in milliseconds) value for DNS queries.
+* Default timeout (in milliseconds) value for DNS queries.
*/
#define TNET_DNS_TIMEOUT_DEFAULT 5000 //(5 seconds)
/**@ingroup tnet_dns_group
-* Maximum supported Dgram size to advertise using EDNS0.
+* Maximum supported Dgram size to advertise using EDNS0.
*/
#define TNET_DNS_DGRAM_SIZE_DEFAULT 4096
@@ -64,17 +64,16 @@ TNET_BEGIN_DECLS
/**DNS cache entry.
*/
-typedef struct tnet_dns_cache_entry_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_dns_cache_entry_s {
+ TSK_DECLARE_OBJECT;
- char* qname;
- tnet_dns_qclass_t qclass;
- tnet_dns_qtype_t qtype;
+ char* qname;
+ tnet_dns_qclass_t qclass;
+ tnet_dns_qtype_t qtype;
- uint64_t epoch;
+ uint64_t epoch;
- tnet_dns_response_t *response;
+ tnet_dns_response_t *response;
}
tnet_dns_cache_entry_t;
typedef tsk_list_t tnet_dns_cache_entries_L_t;
@@ -82,23 +81,22 @@ typedef tnet_dns_cache_entries_L_t tnet_dns_cache_t;
/**DNS context.
*/
-typedef struct tnet_dns_ctx_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_dns_ctx_s {
+ TSK_DECLARE_OBJECT;
+
+ uint64_t timeout; /**< In milliseconds. Default: @ref TNET_DNS_TIMEOUT_DEFAULT. */
+ tsk_bool_t recursion; /**< Indicates whether to direct the name server to pursue the query recursively. Default: enabled.*/
+ tsk_bool_t edns0; /**< Indicates whether to enable EDNS0 (Extension Mechanisms for DNS) or not. This option will allow you to send DNS packet larger than 512 bytes. Default: enabled. */
+ tsk_bool_t caching; /**< Indicates whether to enable the DNS cache or not. Default: no. */
- uint64_t timeout; /**< In milliseconds. Default: @ref TNET_DNS_TIMEOUT_DEFAULT. */
- tsk_bool_t recursion; /**< Indicates whether to direct the name server to pursue the query recursively. Default: enabled.*/
- tsk_bool_t edns0; /**< Indicates whether to enable EDNS0 (Extension Mechanisms for DNS) or not. This option will allow you to send DNS packet larger than 512 bytes. Default: enabled. */
- tsk_bool_t caching; /**< Indicates whether to enable the DNS cache or not. Default: no. */
+ int32_t cache_ttl;
- int32_t cache_ttl;
+ tnet_port_t server_port; /**< Default port (@a TNET_DNS_SERVER_PORT_DEFAULT)) */
- tnet_port_t server_port; /**< Default port (@a TNET_DNS_SERVER_PORT_DEFAULT)) */
+ tnet_dns_cache_t *cache;
+ tnet_addresses_L_t *servers;
- tnet_dns_cache_t *cache;
- tnet_addresses_L_t *servers;
-
- TSK_DECLARE_SAFEOBJ;
+ TSK_DECLARE_SAFEOBJ;
#if HAVE_DNS_H
dns_handle_t resolv_handle;
diff --git a/tinyNET/src/dns/tnet_dns_a.c b/tinyNET/src/dns/tnet_dns_a.c
index 27a3603..b08d056 100755
--- a/tinyNET/src/dns/tnet_dns_a.c
+++ b/tinyNET/src/dns/tnet_dns_a.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,7 +39,7 @@
*/
tnet_dns_a_t* tnet_dns_a_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_a_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_a_def_t, name, qclass, ttl, rdlength, data, offset);
}
@@ -48,55 +48,54 @@ tnet_dns_a_t* tnet_dns_a_create(const char* name, tnet_dns_qclass_t qclass, uint
//
static tsk_object_t* tnet_dns_a_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_a_t *a = self;
- if(a){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_a_t *a = self;
+ if(a) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- const uint8_t* rddata = (((uint8_t*)data) + offset);
- //const uint8_t* dataEnd = (rddata + rdlength);
+ const uint8_t* rddata = (((uint8_t*)data) + offset);
+ //const uint8_t* dataEnd = (rddata + rdlength);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(a), qtype_a, qclass);
- TNET_DNS_RR(a)->name = tsk_strdup(name);
- TNET_DNS_RR(a)->rdlength = rdlength;
- TNET_DNS_RR(a)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(a), qtype_a, qclass);
+ TNET_DNS_RR(a)->name = tsk_strdup(name);
+ TNET_DNS_RR(a)->rdlength = rdlength;
+ TNET_DNS_RR(a)->ttl = ttl;
- if(rddata && rdlength && (rdlength == 4/* 32bits */)){
- // ==> DESERIALIZATION
- /* ADDRESS */
- uint32_t address = (uint32_t)tnet_htonl_2(rddata);
- tsk_sprintf(&(a->address), "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
- }
- else{
- TSK_DEBUG_ERROR("Invalid IPv4 address.");
- }
+ if(rddata && rdlength && (rdlength == 4/* 32bits */)) {
+ // ==> DESERIALIZATION
+ /* ADDRESS */
+ uint32_t address = (uint32_t)tnet_htonl_2(rddata);
+ tsk_sprintf(&(a->address), "%u.%u.%u.%u", (address>>24)&0xFF, (address>>16)&0xFF, (address>>8)&0xFF, (address>>0)&0xFF);
+ }
+ else {
+ TSK_DEBUG_ERROR("Invalid IPv4 address.");
+ }
- }
- return self;
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_a_dtor(tsk_object_t * self)
-{
- tnet_dns_a_t *a = self;
- if(a){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(a));
+static tsk_object_t* tnet_dns_a_dtor(tsk_object_t * self)
+{
+ tnet_dns_a_t *a = self;
+ if(a) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(a));
- TSK_FREE(a->address);
- }
- return self;
+ TSK_FREE(a->address);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_a_def_s =
-{
- sizeof(tnet_dns_a_t),
- tnet_dns_a_ctor,
- tnet_dns_a_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_a_def_s = {
+ sizeof(tnet_dns_a_t),
+ tnet_dns_a_ctor,
+ tnet_dns_a_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_a_def_t = &tnet_dns_a_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_a.h b/tinyNET/src/dns/tnet_dns_a.h
index e5db962..066fe3b 100755
--- a/tinyNET/src/dns/tnet_dns_a.h
+++ b/tinyNET/src/dns/tnet_dns_a.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,16 +38,15 @@ TNET_BEGIN_DECLS
/**DNS A Resource Record.
*/
-typedef struct tnet_dns_a_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_a_s {
+ TNET_DECLARE_DNS_RR;
- /* RFC 1035 - 3.4.1. A RDATA format
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ /* RFC 1035 - 3.4.1. A RDATA format
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ADDRESS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- char* address;
+ */
+ char* address;
}
tnet_dns_a_t;
diff --git a/tinyNET/src/dns/tnet_dns_aaaa.c b/tinyNET/src/dns/tnet_dns_aaaa.c
index 4855827..90cae5b 100755
--- a/tinyNET/src/dns/tnet_dns_aaaa.c
+++ b/tinyNET/src/dns/tnet_dns_aaaa.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -40,7 +40,7 @@
tnet_dns_aaaa_t* tnet_dns_aaaa_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_aaaa_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_aaaa_def_t, name, qclass, ttl, rdlength, data, offset);
}
@@ -49,56 +49,55 @@ tnet_dns_aaaa_t* tnet_dns_aaaa_create(const char* name, tnet_dns_qclass_t qclass
//
static tsk_object_t* tnet_dns_aaaa_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_aaaa_t *aaaa = self;
- if(aaaa){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_aaaa_t *aaaa = self;
+ if(aaaa) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- const uint8_t* rddata = (((uint8_t*)data) + offset);
- //const uint8_t* dataEnd = (rddata + rdlength);
+ const uint8_t* rddata = (((uint8_t*)data) + offset);
+ //const uint8_t* dataEnd = (rddata + rdlength);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(aaaa), qtype_aaaa, qclass);
- TNET_DNS_RR(aaaa)->name = tsk_strdup(name);
- TNET_DNS_RR(aaaa)->rdlength = rdlength;
- TNET_DNS_RR(aaaa)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(aaaa), qtype_aaaa, qclass);
+ TNET_DNS_RR(aaaa)->name = tsk_strdup(name);
+ TNET_DNS_RR(aaaa)->rdlength = rdlength;
+ TNET_DNS_RR(aaaa)->ttl = ttl;
- if(rddata && rdlength && (rdlength == 16/* 128bits */)){
- // ==> DESERIALIZATION
- /* ADDRESS */
- tsk_sprintf(&(aaaa->address), "%x:%x:%x:%x:%x:%x:%x:%x",
- tnet_ntohs_2(&rddata[0]), tnet_ntohs_2(&rddata[2]), tnet_ntohs_2(&rddata[4]), tnet_ntohs_2(&rddata[6]),
- tnet_ntohs_2(&rddata[8]), tnet_ntohs_2(&rddata[10]), tnet_ntohs_2(&rddata[12]), tnet_ntohs_2(&rddata[14]));
- }
- else{
- TSK_DEBUG_ERROR("Invalid IPv6 address.");
- }
+ if(rddata && rdlength && (rdlength == 16/* 128bits */)) {
+ // ==> DESERIALIZATION
+ /* ADDRESS */
+ tsk_sprintf(&(aaaa->address), "%x:%x:%x:%x:%x:%x:%x:%x",
+ tnet_ntohs_2(&rddata[0]), tnet_ntohs_2(&rddata[2]), tnet_ntohs_2(&rddata[4]), tnet_ntohs_2(&rddata[6]),
+ tnet_ntohs_2(&rddata[8]), tnet_ntohs_2(&rddata[10]), tnet_ntohs_2(&rddata[12]), tnet_ntohs_2(&rddata[14]));
+ }
+ else {
+ TSK_DEBUG_ERROR("Invalid IPv6 address.");
+ }
- }
- return self;
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_aaaa_dtor(tsk_object_t * self)
-{
- tnet_dns_aaaa_t *aaaa = self;
- if(aaaa){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(aaaa));
+static tsk_object_t* tnet_dns_aaaa_dtor(tsk_object_t * self)
+{
+ tnet_dns_aaaa_t *aaaa = self;
+ if(aaaa) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(aaaa));
- TSK_FREE(aaaa->address);
- }
- return self;
+ TSK_FREE(aaaa->address);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_aaaa_def_s =
-{
- sizeof(tnet_dns_aaaa_t),
- tnet_dns_aaaa_ctor,
- tnet_dns_aaaa_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_aaaa_def_s = {
+ sizeof(tnet_dns_aaaa_t),
+ tnet_dns_aaaa_ctor,
+ tnet_dns_aaaa_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_aaaa_def_t = &tnet_dns_aaaa_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_aaaa.h b/tinyNET/src/dns/tnet_dns_aaaa.h
index 759adf1..7fdd018 100755
--- a/tinyNET/src/dns/tnet_dns_aaaa.h
+++ b/tinyNET/src/dns/tnet_dns_aaaa.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,13 +38,12 @@ TNET_BEGIN_DECLS
/**DNS AAAA Resource Record.
*/
-typedef struct tnet_dns_aaaa_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_aaaa_s {
+ TNET_DECLARE_DNS_RR;
- /* RFC 3596 -
- */
- char* address;
+ /* RFC 3596 -
+ */
+ char* address;
}
tnet_dns_aaaa_t;
diff --git a/tinyNET/src/dns/tnet_dns_cname.c b/tinyNET/src/dns/tnet_dns_cname.c
index 8bec3e8..e64d515 100755
--- a/tinyNET/src/dns/tnet_dns_cname.c
+++ b/tinyNET/src/dns/tnet_dns_cname.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,7 +38,7 @@
tnet_dns_cname_t* tnet_dns_cname_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_cname_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_cname_def_t, name, qclass, ttl, rdlength, data, offset);
}
@@ -47,47 +47,46 @@ tnet_dns_cname_t* tnet_dns_cname_create(const char* name, tnet_dns_qclass_t qcla
//
static tsk_object_t* tnet_dns_cname_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_cname_t *cname = self;
- if(cname){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_cname_t *cname = self;
+ if(cname) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(cname), qtype_cname, qclass);
- TNET_DNS_RR(cname)->name = tsk_strdup(name);
- TNET_DNS_RR(cname)->rdlength = rdlength;
- TNET_DNS_RR(cname)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(cname), qtype_cname, qclass);
+ TNET_DNS_RR(cname)->name = tsk_strdup(name);
+ TNET_DNS_RR(cname)->rdlength = rdlength;
+ TNET_DNS_RR(cname)->ttl = ttl;
- if(rdlength){
- // ==> DESERIALIZATION
- /* CNAME */
- tnet_dns_rr_qname_deserialize(data, &(cname->cname), &offset);
- }
- }
- return self;
+ if(rdlength) {
+ // ==> DESERIALIZATION
+ /* CNAME */
+ tnet_dns_rr_qname_deserialize(data, &(cname->cname), &offset);
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_cname_dtor(tsk_object_t * self)
-{
- tnet_dns_cname_t *cname = self;
- if(cname){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(cname));
+static tsk_object_t* tnet_dns_cname_dtor(tsk_object_t * self)
+{
+ tnet_dns_cname_t *cname = self;
+ if(cname) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(cname));
- TSK_FREE(cname->cname);
- }
- return self;
+ TSK_FREE(cname->cname);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_cname_def_s =
-{
- sizeof(tnet_dns_cname_t),
- tnet_dns_cname_ctor,
- tnet_dns_cname_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_cname_def_s = {
+ sizeof(tnet_dns_cname_t),
+ tnet_dns_cname_ctor,
+ tnet_dns_cname_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_cname_def_t = &tnet_dns_cname_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_cname.h b/tinyNET/src/dns/tnet_dns_cname.h
index f97087d..8d8b658 100755
--- a/tinyNET/src/dns/tnet_dns_cname.h
+++ b/tinyNET/src/dns/tnet_dns_cname.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,17 +39,16 @@ TNET_BEGIN_DECLS
/** DNS CNAME Resource Record
*/
-typedef struct tnet_dns_cname_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_cname_s {
+ TNET_DECLARE_DNS_RR;
- /* 3.3.1. CNAME RDATA format
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ /* 3.3.1. CNAME RDATA format
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/ CNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- char* cname;
+ */
+ char* cname;
}
tnet_dns_cname_t;
diff --git a/tinyNET/src/dns/tnet_dns_message.c b/tinyNET/src/dns/tnet_dns_message.c
index 594f499..4c1ef76 100755
--- a/tinyNET/src/dns/tnet_dns_message.c
+++ b/tinyNET/src/dns/tnet_dns_message.c
@@ -38,7 +38,7 @@
*/
tnet_dns_message_t* tnet_dns_message_create(const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype, tsk_bool_t isquery)
{
- return tsk_object_new(tnet_dns_message_def_t, qname, qclass, qtype, isquery);
+ return tsk_object_new(tnet_dns_message_def_t, qname, qclass, qtype, isquery);
}
/**@ingroup tnet_dns_group
@@ -47,7 +47,7 @@ tnet_dns_message_t* tnet_dns_message_create(const char* qname, tnet_dns_qclass_t
*/
tnet_dns_message_t* tnet_dns_message_create_null()
{
- return tnet_dns_message_create(tsk_null, qclass_any, qtype_any, tsk_false);
+ return tnet_dns_message_create(tsk_null, qclass_any, qtype_any, tsk_false);
}
/**@ingroup tnet_dns_group
@@ -56,7 +56,7 @@ tnet_dns_message_t* tnet_dns_message_create_null()
*/
tnet_dns_response_t* tnet_dns_response_create(const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype)
{
- return tnet_dns_message_create(qname, qclass, qtype, tsk_false);
+ return tnet_dns_message_create(qname, qclass, qtype, tsk_false);
}
/**@ingroup tnet_dns_group
@@ -65,7 +65,7 @@ tnet_dns_response_t* tnet_dns_response_create(const char* qname, tnet_dns_qclass
*/
tnet_dns_query_t* tnet_dns_query_create(const char* qname, tnet_dns_qclass_t qclass, tnet_dns_qtype_t qtype)
{
- return tnet_dns_message_create(qname, qclass, qtype, tsk_true);
+ return tnet_dns_message_create(qname, qclass, qtype, tsk_true);
}
/**@ingroup tnet_dns_group
@@ -76,113 +76,109 @@ tnet_dns_query_t* tnet_dns_query_create(const char* qname, tnet_dns_qclass_t qcl
*/
tsk_buffer_t* tnet_dns_message_serialize(const tnet_dns_message_t *message)
{
- tsk_buffer_t* output = tsk_null;
- uint16_t _2bytes;
- tsk_list_item_t *item;
-
- /* Check message validity */
- if (!message){
- goto bail;
- }
-
- /* Creates empty buffer */
- output = tsk_buffer_create_null();
-
- /* ==============================
- * HEADER
- */
- //tsk_buffer_append(output, &(message->Header), sizeof(message->Header));
-
- /* ID */
- _2bytes = tnet_ntohs(message->Header.ID);
- tsk_buffer_append(output, &(_2bytes), 2);
- /* |QR| Opcode |AA|TC|RD|RA| Z | RCODE | */
- {
- uint16_t temp, _2bytes = 0;
-
- temp = message->Header.QR, temp <<= 15;
- _2bytes |= temp;
-
- temp = message->Header.OPCODE, temp <<= 11;
- _2bytes |= temp;
-
- temp = message->Header.AA, temp <<= 10;
- _2bytes |= temp;
-
- temp = message->Header.TC, temp <<= 9;
- _2bytes |= temp;
-
- temp = message->Header.RD, temp <<= 8;
- _2bytes |= temp;
-
- temp = message->Header.RA, temp <<= 7;
- _2bytes |= temp;
-
- temp = message->Header.Z, temp <<= 4;
- _2bytes |= temp;
-
- temp = message->Header.RCODE, temp <<= 4;
- _2bytes |= temp;
-
- _2bytes = tnet_ntohs(_2bytes);
- tsk_buffer_append(output, &(_2bytes), 2);
- }
- /* QDCOUNT */
- _2bytes = tnet_ntohs(message->Header.QDCOUNT);
- tsk_buffer_append(output, &(_2bytes), 2);
- /* ANCOUNT */
- _2bytes = tnet_ntohs(message->Header.ANCOUNT);
- tsk_buffer_append(output, &(_2bytes), 2);
- /* NSCOUNT */
- _2bytes = tnet_ntohs(message->Header.NSCOUNT);
- tsk_buffer_append(output, &(_2bytes), 2);
- /* ARCOUNT */
- _2bytes = tnet_ntohs(message->Header.ARCOUNT);
- tsk_buffer_append(output, &(_2bytes), 2);
-
-
- /* ==============================
- * QUESTION
- */
- if (TNET_DNS_MESSAGE_IS_QUERY(message))
- {
- /* QNAME */
- tnet_dns_rr_qname_serialize(message->Question.QNAME, output);
- /* QTYPE */
- _2bytes = tnet_ntohs(message->Question.QTYPE);
- tsk_buffer_append(output, &(_2bytes), 2);
- /* QCLASS */
- _2bytes = tnet_ntohs(message->Question.QCLASS);
- tsk_buffer_append(output, &(_2bytes), 2);
- }
-
- /* ==============================
- * ANSWERS
- */
- tsk_list_foreach(item, message->Answers)
- {
- tnet_dns_rr_serialize((tnet_dns_rr_t *)item->data, output);
- }
-
- /* ==============================
- * AUTHORITIES
- */
- tsk_list_foreach(item, message->Authorities)
- {
- tnet_dns_rr_serialize((tnet_dns_rr_t *)item->data, output);
- }
-
- /* ==============================
- * ADDITIONALS
- */
- tsk_list_foreach(item, message->Additionals)
- {
- tnet_dns_rr_serialize((tnet_dns_rr_t *)item->data, output);
- }
+ tsk_buffer_t* output = tsk_null;
+ uint16_t _2bytes;
+ tsk_list_item_t *item;
+
+ /* Check message validity */
+ if (!message) {
+ goto bail;
+ }
+
+ /* Creates empty buffer */
+ output = tsk_buffer_create_null();
+
+ /* ==============================
+ * HEADER
+ */
+ //tsk_buffer_append(output, &(message->Header), sizeof(message->Header));
+
+ /* ID */
+ _2bytes = tnet_ntohs(message->Header.ID);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /* |QR| Opcode |AA|TC|RD|RA| Z | RCODE | */
+ {
+ uint16_t temp, _2bytes = 0;
+
+ temp = message->Header.QR, temp <<= 15;
+ _2bytes |= temp;
+
+ temp = message->Header.OPCODE, temp <<= 11;
+ _2bytes |= temp;
+
+ temp = message->Header.AA, temp <<= 10;
+ _2bytes |= temp;
+
+ temp = message->Header.TC, temp <<= 9;
+ _2bytes |= temp;
+
+ temp = message->Header.RD, temp <<= 8;
+ _2bytes |= temp;
+
+ temp = message->Header.RA, temp <<= 7;
+ _2bytes |= temp;
+
+ temp = message->Header.Z, temp <<= 4;
+ _2bytes |= temp;
+
+ temp = message->Header.RCODE, temp <<= 4;
+ _2bytes |= temp;
+
+ _2bytes = tnet_ntohs(_2bytes);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ }
+ /* QDCOUNT */
+ _2bytes = tnet_ntohs(message->Header.QDCOUNT);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /* ANCOUNT */
+ _2bytes = tnet_ntohs(message->Header.ANCOUNT);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /* NSCOUNT */
+ _2bytes = tnet_ntohs(message->Header.NSCOUNT);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /* ARCOUNT */
+ _2bytes = tnet_ntohs(message->Header.ARCOUNT);
+ tsk_buffer_append(output, &(_2bytes), 2);
+
+
+ /* ==============================
+ * QUESTION
+ */
+ if (TNET_DNS_MESSAGE_IS_QUERY(message)) {
+ /* QNAME */
+ tnet_dns_rr_qname_serialize(message->Question.QNAME, output);
+ /* QTYPE */
+ _2bytes = tnet_ntohs(message->Question.QTYPE);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ /* QCLASS */
+ _2bytes = tnet_ntohs(message->Question.QCLASS);
+ tsk_buffer_append(output, &(_2bytes), 2);
+ }
+
+ /* ==============================
+ * ANSWERS
+ */
+ tsk_list_foreach(item, message->Answers) {
+ tnet_dns_rr_serialize((tnet_dns_rr_t *)item->data, output);
+ }
+
+ /* ==============================
+ * AUTHORITIES
+ */
+ tsk_list_foreach(item, message->Authorities) {
+ tnet_dns_rr_serialize((tnet_dns_rr_t *)item->data, output);
+ }
+
+ /* ==============================
+ * ADDITIONALS
+ */
+ tsk_list_foreach(item, message->Additionals) {
+ tnet_dns_rr_serialize((tnet_dns_rr_t *)item->data, output);
+ }
bail:
- return output;
+ return output;
}
/**@ingroup tnet_dns_group
@@ -194,112 +190,108 @@ bail:
*/
tnet_dns_message_t* tnet_dns_message_deserialize(const uint8_t *data, tsk_size_t size)
{
- tnet_dns_message_t *message = 0;
- uint8_t *dataPtr, *dataEnd, *dataStart;
- uint16_t i;
- tsk_size_t offset = 0;
-
- if (!data || !size){
- goto bail;
- }
-
- dataPtr = (uint8_t*)data;
- dataStart = dataPtr;
- dataEnd = (dataStart + size);
-
- message = tnet_dns_message_create_null();
-
- /* === HEADER ===*/
- /* ID */
- message->Header.ID = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
- /* |QR| Opcode |AA|TC|RD|RA| Z | RCODE | */
- {
- uint16_t flags = tnet_ntohs_2(dataPtr);
-
- message->Header.QR = (flags >> 15);
- message->Header.OPCODE = ((flags >> 11) & 0x000F);
- message->Header.AA = ((flags >> 10) & 0x0001);
- message->Header.TC = ((flags >> 9) & 0x0001);
- message->Header.RD = ((flags >> 8) & 0x0001);
- message->Header.RA = ((flags >> 7) & 0x0001);
- message->Header.Z = ((flags >> 4) & 0x0007);
- message->Header.RCODE = (flags & 0x000F);
-
- dataPtr += 2;
- }
- /* QDCOUNT */
- message->Header.QDCOUNT = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
- /* ANCOUNT */
- message->Header.ANCOUNT = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
- /* NSCOUNT */
- message->Header.NSCOUNT = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
- /* ARCOUNT */
- message->Header.ARCOUNT = tnet_ntohs_2(dataPtr);
- dataPtr += 2;
-
- /* === Queries ===*/
- offset = (tsk_size_t)(dataPtr - dataStart);
- for (i = 0; i < message->Header.QDCOUNT; i++)
- {
- /* Do not need to parse queries in the response ==> silently ignore */
- char* name = 0;
- tnet_dns_rr_qname_deserialize(dataStart, &name, &offset); /* QNAME */
- dataPtr += offset;
- dataPtr += 4, offset += 4; /* QTYPE + QCLASS */
- TSK_FREE(name);
- }
- dataPtr = (dataStart + offset); /* TODO: remove ==> obly for debug tests */
-
- /* === Answers ===*/
- offset = (tsk_size_t)(dataPtr - dataStart);
- for (i = 0; i < message->Header.ANCOUNT; i++)
- {
- tnet_dns_rr_t* rr = tnet_dns_rr_deserialize(dataStart, (tsk_size_t)(dataEnd - dataPtr), &offset);
- if (rr){
- if (!message->Answers){
- message->Answers = tsk_list_create();
- }
- /* Push in descending order (useful for NAPTR and SRV records). */
- tsk_list_push_descending_data(message->Answers, (void**)&rr);
- }
- }
- dataPtr = (dataStart + offset);
-
- /* === Authorities ===*/
- offset = (tsk_size_t)(dataPtr - dataStart);
- for (i = 0; i < message->Header.NSCOUNT; i++)
- {
- tnet_dns_rr_t* rr = tnet_dns_rr_deserialize(dataStart, (tsk_size_t)(dataEnd - dataPtr), &offset);
- if (rr){
- if (!message->Authorities){
- message->Authorities = tsk_list_create();
- }
- tsk_list_push_back_data(message->Authorities, (void**)&rr);
- }
- }
- dataPtr = (dataStart + offset);
-
- /* === Additionals ===*/
- offset = (tsk_size_t)(dataPtr - dataStart);
- for (i = 0; i < message->Header.ARCOUNT; i++)
- {
- tnet_dns_rr_t* rr = tnet_dns_rr_deserialize(dataStart, (tsk_size_t)(dataEnd - dataPtr), &offset);
- if (rr){
- if (!message->Additionals){
- message->Additionals = tsk_list_create();
- }
- tsk_list_push_back_data(message->Additionals, (void**)&rr);
- }
- }
- dataPtr = (dataStart + offset);
+ tnet_dns_message_t *message = 0;
+ uint8_t *dataPtr, *dataEnd, *dataStart;
+ uint16_t i;
+ tsk_size_t offset = 0;
+
+ if (!data || !size) {
+ goto bail;
+ }
+
+ dataPtr = (uint8_t*)data;
+ dataStart = dataPtr;
+ dataEnd = (dataStart + size);
+
+ message = tnet_dns_message_create_null();
+
+ /* === HEADER ===*/
+ /* ID */
+ message->Header.ID = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+ /* |QR| Opcode |AA|TC|RD|RA| Z | RCODE | */
+ {
+ uint16_t flags = tnet_ntohs_2(dataPtr);
+
+ message->Header.QR = (flags >> 15);
+ message->Header.OPCODE = ((flags >> 11) & 0x000F);
+ message->Header.AA = ((flags >> 10) & 0x0001);
+ message->Header.TC = ((flags >> 9) & 0x0001);
+ message->Header.RD = ((flags >> 8) & 0x0001);
+ message->Header.RA = ((flags >> 7) & 0x0001);
+ message->Header.Z = ((flags >> 4) & 0x0007);
+ message->Header.RCODE = (flags & 0x000F);
+
+ dataPtr += 2;
+ }
+ /* QDCOUNT */
+ message->Header.QDCOUNT = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+ /* ANCOUNT */
+ message->Header.ANCOUNT = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+ /* NSCOUNT */
+ message->Header.NSCOUNT = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+ /* ARCOUNT */
+ message->Header.ARCOUNT = tnet_ntohs_2(dataPtr);
+ dataPtr += 2;
+
+ /* === Queries ===*/
+ offset = (tsk_size_t)(dataPtr - dataStart);
+ for (i = 0; i < message->Header.QDCOUNT; i++) {
+ /* Do not need to parse queries in the response ==> silently ignore */
+ char* name = 0;
+ tnet_dns_rr_qname_deserialize(dataStart, &name, &offset); /* QNAME */
+ dataPtr += offset;
+ dataPtr += 4, offset += 4; /* QTYPE + QCLASS */
+ TSK_FREE(name);
+ }
+ dataPtr = (dataStart + offset); /* TODO: remove ==> obly for debug tests */
+
+ /* === Answers ===*/
+ offset = (tsk_size_t)(dataPtr - dataStart);
+ for (i = 0; i < message->Header.ANCOUNT; i++) {
+ tnet_dns_rr_t* rr = tnet_dns_rr_deserialize(dataStart, (tsk_size_t)(dataEnd - dataPtr), &offset);
+ if (rr) {
+ if (!message->Answers) {
+ message->Answers = tsk_list_create();
+ }
+ /* Push in descending order (useful for NAPTR and SRV records). */
+ tsk_list_push_descending_data(message->Answers, (void**)&rr);
+ }
+ }
+ dataPtr = (dataStart + offset);
+
+ /* === Authorities ===*/
+ offset = (tsk_size_t)(dataPtr - dataStart);
+ for (i = 0; i < message->Header.NSCOUNT; i++) {
+ tnet_dns_rr_t* rr = tnet_dns_rr_deserialize(dataStart, (tsk_size_t)(dataEnd - dataPtr), &offset);
+ if (rr) {
+ if (!message->Authorities) {
+ message->Authorities = tsk_list_create();
+ }
+ tsk_list_push_back_data(message->Authorities, (void**)&rr);
+ }
+ }
+ dataPtr = (dataStart + offset);
+
+ /* === Additionals ===*/
+ offset = (tsk_size_t)(dataPtr - dataStart);
+ for (i = 0; i < message->Header.ARCOUNT; i++) {
+ tnet_dns_rr_t* rr = tnet_dns_rr_deserialize(dataStart, (tsk_size_t)(dataEnd - dataPtr), &offset);
+ if (rr) {
+ if (!message->Additionals) {
+ message->Additionals = tsk_list_create();
+ }
+ tsk_list_push_back_data(message->Additionals, (void**)&rr);
+ }
+ }
+ dataPtr = (dataStart + offset);
bail:
- return message;
+ return message;
}
//=================================================================================================
@@ -307,53 +299,52 @@ bail:
//
static tsk_object_t* tnet_dns_message_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_message_t *message = self;
- if (message){
- static uint16_t __dnsmessage_unique_id = 0;
-
- const char* qname = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- tnet_dns_qtype_t qtype = va_arg(*app, tnet_dns_qtype_t);
- tsk_bool_t isquery = va_arg(*app, tsk_bool_t);
-
- /* Create random ID. */
- message->Header.ID = ++__dnsmessage_unique_id;
-
- /* QR field ==> query (0) - response (1) */
- message->Header.QR = isquery ? 0 : 1;
-
- if (isquery){
- /* QDCOUNT field ==> at least one question */
- message->Header.QDCOUNT = 1;
- }
-
- if (qname){
- message->Question.QNAME = tsk_strdup(qname);
- message->Question.QTYPE = qtype;
- message->Question.QCLASS = qclass;
- }
- }
- return self;
+ tnet_dns_message_t *message = self;
+ if (message) {
+ static uint16_t __dnsmessage_unique_id = 0;
+
+ const char* qname = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ tnet_dns_qtype_t qtype = va_arg(*app, tnet_dns_qtype_t);
+ tsk_bool_t isquery = va_arg(*app, tsk_bool_t);
+
+ /* Create random ID. */
+ message->Header.ID = ++__dnsmessage_unique_id;
+
+ /* QR field ==> query (0) - response (1) */
+ message->Header.QR = isquery ? 0 : 1;
+
+ if (isquery) {
+ /* QDCOUNT field ==> at least one question */
+ message->Header.QDCOUNT = 1;
+ }
+
+ if (qname) {
+ message->Question.QNAME = tsk_strdup(qname);
+ message->Question.QTYPE = qtype;
+ message->Question.QCLASS = qclass;
+ }
+ }
+ return self;
}
static tsk_object_t* tnet_dns_message_dtor(tsk_object_t * self)
{
- tnet_dns_message_t *message = self;
- if (message){
- TSK_FREE(message->Question.QNAME);
-
- TSK_OBJECT_SAFE_FREE(message->Answers);
- TSK_OBJECT_SAFE_FREE(message->Authorities);
- TSK_OBJECT_SAFE_FREE(message->Additionals);
- }
- return self;
+ tnet_dns_message_t *message = self;
+ if (message) {
+ TSK_FREE(message->Question.QNAME);
+
+ TSK_OBJECT_SAFE_FREE(message->Answers);
+ TSK_OBJECT_SAFE_FREE(message->Authorities);
+ TSK_OBJECT_SAFE_FREE(message->Additionals);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_message_def_s =
-{
- sizeof(tnet_dns_message_t),
- tnet_dns_message_ctor,
- tnet_dns_message_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_message_def_s = {
+ sizeof(tnet_dns_message_t),
+ tnet_dns_message_ctor,
+ tnet_dns_message_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_message_def_t = &tnet_dns_message_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_message.h b/tinyNET/src/dns/tnet_dns_message.h
index 8506ff8..bea318a 100755
--- a/tinyNET/src/dns/tnet_dns_message.h
+++ b/tinyNET/src/dns/tnet_dns_message.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -68,22 +68,20 @@ TNET_BEGIN_DECLS
/**Response codes as per RFC 1035 subclause 4.1.1.
*/
-typedef enum tnet_dns_rcode_e
-{
- rcode_noerror = 0,
- rcode_error_format = 1,
- rcode_server_failure = 2,
- rcode_error_name = 3,
- rcode_notimplemented = 4,
- rcode_refused = 5
+typedef enum tnet_dns_rcode_e {
+ rcode_noerror = 0,
+ rcode_error_format = 1,
+ rcode_server_failure = 2,
+ rcode_error_name = 3,
+ rcode_notimplemented = 4,
+ rcode_refused = 5
}
tnet_dns_rcode_t;
/**OPCODE defining the kind of query as per RFC 1035 subclause 4.1.1.
*/
-typedef enum tnet_dns_opcode_e
-{
- opcode_query = 0, /**< 0 a standard query (QUERY) */
+typedef enum tnet_dns_opcode_e {
+ opcode_query = 0, /**< 0 a standard query (QUERY) */
opcode_iquery = 1, /**< 1 an inverse query (IQUERY) */
opcode_status = 2, /**< 2 a server status request (STATUS) */
}
@@ -91,12 +89,11 @@ tnet_dns_opcode_t;
/** DNS message as per RFC 1035 subclause 4.
*/
-typedef struct tnet_dns_message_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_dns_message_s {
+ TSK_DECLARE_OBJECT;
- /* RFC 1035 - 4.1. Format
- +---------------------+
+ /* RFC 1035 - 4.1. Format
+ +---------------------+
| Header |
+---------------------+
| Question | the question for the name server
@@ -107,10 +104,10 @@ typedef struct tnet_dns_message_s
+---------------------+
| Additional | RRs holding additional information
+---------------------+
- */
+ */
- /* RFC 1035 - 4.1.1. Header section format
- 1 1 1 1 1 1
+ /* RFC 1035 - 4.1.1. Header section format
+ 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
@@ -125,27 +122,26 @@ typedef struct tnet_dns_message_s
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- struct
- {
- uint16_t ID;
- unsigned QR:1;
- unsigned OPCODE:4; /* see @ref tnet_dns_opcode_t */
- unsigned AA:1;
- unsigned TC:1;
- unsigned RD:1;
- unsigned RA:1;
- unsigned Z:3;
- unsigned RCODE:4; /* see @ref tnet_dns_rcode_t */
- uint16_t QDCOUNT;
- uint16_t ANCOUNT;
- uint16_t NSCOUNT;
- uint16_t ARCOUNT;
- }
- Header;
-
- /* RFc 1035 - 4.1.2. Question section format
- 1 1 1 1 1 1
+ */
+ struct {
+ uint16_t ID;
+ unsigned QR:1;
+ unsigned OPCODE:4; /* see @ref tnet_dns_opcode_t */
+ unsigned AA:1;
+ unsigned TC:1;
+ unsigned RD:1;
+ unsigned RA:1;
+ unsigned Z:3;
+ unsigned RCODE:4; /* see @ref tnet_dns_rcode_t */
+ uint16_t QDCOUNT;
+ uint16_t ANCOUNT;
+ uint16_t NSCOUNT;
+ uint16_t ARCOUNT;
+ }
+ Header;
+
+ /* RFc 1035 - 4.1.2. Question section format
+ 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
@@ -156,34 +152,33 @@ typedef struct tnet_dns_message_s
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- struct
- {
- /** RFC 1035 - 4.1.2. Question section format
- a domain name represented as a sequence of labels, where
- each label consists of a length octet followed by that
- number of octets. The domain name terminates with the
- zero length octet for the null label of the root. Note
- that this field may be an odd number of octets; no
- padding is used.*/
- void* QNAME;
- /** RFC 1035 - 4.1.2. Question section format
- a two octet code which specifies the type of the query.
- The values for this field include all codes valid for a
- TYPE field, together with some more general codes which
- can match more than one type of RR.*/
- tnet_dns_qtype_t QTYPE;
- /* RFC 1035 - 4.1.2. Question section format
- a two octet code that specifies the class of the query.
- For example, the QCLASS field is IN for the Internet.
- */
- tnet_dns_qclass_t QCLASS;
- }
- Question;
-
- tnet_dns_rrs_L_t *Answers; /**< Filtered answers by priority. */
- tnet_dns_rrs_L_t *Authorities;
- tnet_dns_rrs_L_t *Additionals;
+ */
+ struct {
+ /** RFC 1035 - 4.1.2. Question section format
+ a domain name represented as a sequence of labels, where
+ each label consists of a length octet followed by that
+ number of octets. The domain name terminates with the
+ zero length octet for the null label of the root. Note
+ that this field may be an odd number of octets; no
+ padding is used.*/
+ void* QNAME;
+ /** RFC 1035 - 4.1.2. Question section format
+ a two octet code which specifies the type of the query.
+ The values for this field include all codes valid for a
+ TYPE field, together with some more general codes which
+ can match more than one type of RR.*/
+ tnet_dns_qtype_t QTYPE;
+ /* RFC 1035 - 4.1.2. Question section format
+ a two octet code that specifies the class of the query.
+ For example, the QCLASS field is IN for the Internet.
+ */
+ tnet_dns_qclass_t QCLASS;
+ }
+ Question;
+
+ tnet_dns_rrs_L_t *Answers; /**< Filtered answers by priority. */
+ tnet_dns_rrs_L_t *Authorities;
+ tnet_dns_rrs_L_t *Additionals;
}
tnet_dns_message_t;
diff --git a/tinyNET/src/dns/tnet_dns_mx.c b/tinyNET/src/dns/tnet_dns_mx.c
index edc59b1..5b8b801 100755
--- a/tinyNET/src/dns/tnet_dns_mx.c
+++ b/tinyNET/src/dns/tnet_dns_mx.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,7 +38,7 @@
*/
tnet_dns_mx_t* tnet_dns_mx_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_mx_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_mx_def_t, name, qclass, ttl, rdlength, data, offset);
}
//=================================================================================================
@@ -46,50 +46,49 @@ tnet_dns_mx_t* tnet_dns_mx_create(const char* name, tnet_dns_qclass_t qclass, ui
//
static tsk_object_t* tnet_dns_mx_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_mx_t *mx = self;
- if(mx){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_mx_t *mx = self;
+ if(mx) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(mx), qtype_mx, qclass);
- TNET_DNS_RR(mx)->name = tsk_strdup(name);
- TNET_DNS_RR(mx)->rdlength = rdlength;
- TNET_DNS_RR(mx)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(mx), qtype_mx, qclass);
+ TNET_DNS_RR(mx)->name = tsk_strdup(name);
+ TNET_DNS_RR(mx)->rdlength = rdlength;
+ TNET_DNS_RR(mx)->ttl = ttl;
- if(rdlength){
- // ==> DESERIALIZATION
- /* PREFERENCE */
- mx->preference = tnet_ntohs_2(((uint8_t*)data) + offset);
- offset += 2;
- /* EXCHANGE */
- tnet_dns_rr_qname_deserialize(data, &(mx->exchange), &offset);
- }
- }
- return self;
+ if(rdlength) {
+ // ==> DESERIALIZATION
+ /* PREFERENCE */
+ mx->preference = tnet_ntohs_2(((uint8_t*)data) + offset);
+ offset += 2;
+ /* EXCHANGE */
+ tnet_dns_rr_qname_deserialize(data, &(mx->exchange), &offset);
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_mx_dtor(tsk_object_t * self)
-{
- tnet_dns_mx_t *mx = self;
- if(mx){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(mx));
+static tsk_object_t* tnet_dns_mx_dtor(tsk_object_t * self)
+{
+ tnet_dns_mx_t *mx = self;
+ if(mx) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(mx));
- TSK_FREE(mx->exchange);
- }
- return self;
+ TSK_FREE(mx->exchange);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_mx_def_s =
-{
- sizeof(tnet_dns_mx_t),
- tnet_dns_mx_ctor,
- tnet_dns_mx_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_mx_def_s = {
+ sizeof(tnet_dns_mx_t),
+ tnet_dns_mx_ctor,
+ tnet_dns_mx_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_mx_def_t = &tnet_dns_mx_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_mx.h b/tinyNET/src/dns/tnet_dns_mx.h
index 98a00f1..6c0b999 100755
--- a/tinyNET/src/dns/tnet_dns_mx.h
+++ b/tinyNET/src/dns/tnet_dns_mx.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,20 +39,19 @@ TNET_BEGIN_DECLS
/** DNS MX Resource Record
*/
-typedef struct tnet_dns_mx_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_mx_s {
+ TNET_DECLARE_DNS_RR;
- /* RFC 1035 - 3.3.9. MX RDATA format
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ /* RFC 1035 - 3.3.9. MX RDATA format
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| PREFERENCE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/ EXCHANGE /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- uint16_t preference;
- char* exchange;
+ */
+ uint16_t preference;
+ char* exchange;
}
tnet_dns_mx_t;
diff --git a/tinyNET/src/dns/tnet_dns_naptr.c b/tinyNET/src/dns/tnet_dns_naptr.c
index 79d7f70..c69f168 100755
--- a/tinyNET/src/dns/tnet_dns_naptr.c
+++ b/tinyNET/src/dns/tnet_dns_naptr.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,7 +39,7 @@
*/
tnet_dns_naptr_t* tnet_dns_naptr_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_naptr_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_naptr_def_t, name, qclass, ttl, rdlength, data, offset);
}
@@ -49,94 +49,93 @@ tnet_dns_naptr_t* tnet_dns_naptr_create(const char* name, tnet_dns_qclass_t qcla
//
static tsk_object_t* tnet_dns_naptr_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_naptr_t *naptr = self;
- if(naptr){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
-
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(naptr), qtype_naptr, qclass);
- TNET_DNS_RR(naptr)->name = tsk_strdup(name);
- TNET_DNS_RR(naptr)->rdlength = rdlength;
- TNET_DNS_RR(naptr)->ttl = ttl;
-
- if(rdlength){
- // ==> DESERIALIZATION
- /* ORDER */
- naptr->order = tnet_ntohs_2(((uint8_t*)data) + offset);
- offset += 2;
- /* PREFERENCE */
- naptr->preference = tnet_ntohs_2(((uint8_t*)data) + offset);
- offset += 2;
- /* FLAGS */
- tnet_dns_rr_charstring_deserialize(data, &(naptr->flags), &offset);
- /* SERVICES */
- tnet_dns_rr_charstring_deserialize(data, &(naptr->services), &offset);
- /* REGEXP */
- tnet_dns_rr_charstring_deserialize(data, &(naptr->regexp), &offset);
- /* REPLACEMENT */
- tnet_dns_rr_qname_deserialize(data, &(naptr->replacement), &offset);
- }
- }
- return self;
+ tnet_dns_naptr_t *naptr = self;
+ if(naptr) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
+
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(naptr), qtype_naptr, qclass);
+ TNET_DNS_RR(naptr)->name = tsk_strdup(name);
+ TNET_DNS_RR(naptr)->rdlength = rdlength;
+ TNET_DNS_RR(naptr)->ttl = ttl;
+
+ if(rdlength) {
+ // ==> DESERIALIZATION
+ /* ORDER */
+ naptr->order = tnet_ntohs_2(((uint8_t*)data) + offset);
+ offset += 2;
+ /* PREFERENCE */
+ naptr->preference = tnet_ntohs_2(((uint8_t*)data) + offset);
+ offset += 2;
+ /* FLAGS */
+ tnet_dns_rr_charstring_deserialize(data, &(naptr->flags), &offset);
+ /* SERVICES */
+ tnet_dns_rr_charstring_deserialize(data, &(naptr->services), &offset);
+ /* REGEXP */
+ tnet_dns_rr_charstring_deserialize(data, &(naptr->regexp), &offset);
+ /* REPLACEMENT */
+ tnet_dns_rr_qname_deserialize(data, &(naptr->replacement), &offset);
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_naptr_dtor(tsk_object_t * self)
-{
- tnet_dns_naptr_t *naptr = self;
- if(naptr){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(naptr));
-
- TSK_FREE(naptr->flags);
- TSK_FREE(naptr->services);
- TSK_FREE(naptr->regexp);
- TSK_FREE(naptr->replacement);
- }
- return self;
+static tsk_object_t* tnet_dns_naptr_dtor(tsk_object_t * self)
+{
+ tnet_dns_naptr_t *naptr = self;
+ if(naptr) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(naptr));
+
+ TSK_FREE(naptr->flags);
+ TSK_FREE(naptr->services);
+ TSK_FREE(naptr->regexp);
+ TSK_FREE(naptr->replacement);
+ }
+ return self;
}
static int tnet_dns_naptr_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2)
-{
- const tnet_dns_rr_t* rr1 = obj1;
- const tnet_dns_rr_t* rr2 = obj2;
-
- if(rr1 && rr2 && (rr1->qtype==qtype_naptr) && (rr2->qtype==qtype_naptr)){
- const tnet_dns_naptr_t* naptr1 = (tnet_dns_naptr_t*)rr1;
- const tnet_dns_naptr_t* naptr2 = (tnet_dns_naptr_t*)rr2;
-
- /* Compare orders. */
- if(naptr1->order < naptr2->order){ /* Lowest order is tried first. */
- return 1;
- }
- else if(naptr1->order > naptr2->order){
- return -1;
- }
-
- /* Compare preference */
- if(naptr1->order < naptr2->order){ /* Lowest preference is tried first. */
- return 1;
- }
- else if(naptr1->order > naptr2->order){
- return -1;
- }
-
- return 0;
- }
- else{
- return -1;
- }
+{
+ const tnet_dns_rr_t* rr1 = obj1;
+ const tnet_dns_rr_t* rr2 = obj2;
+
+ if(rr1 && rr2 && (rr1->qtype==qtype_naptr) && (rr2->qtype==qtype_naptr)) {
+ const tnet_dns_naptr_t* naptr1 = (tnet_dns_naptr_t*)rr1;
+ const tnet_dns_naptr_t* naptr2 = (tnet_dns_naptr_t*)rr2;
+
+ /* Compare orders. */
+ if(naptr1->order < naptr2->order) { /* Lowest order is tried first. */
+ return 1;
+ }
+ else if(naptr1->order > naptr2->order) {
+ return -1;
+ }
+
+ /* Compare preference */
+ if(naptr1->order < naptr2->order) { /* Lowest preference is tried first. */
+ return 1;
+ }
+ else if(naptr1->order > naptr2->order) {
+ return -1;
+ }
+
+ return 0;
+ }
+ else {
+ return -1;
+ }
}
-static const tsk_object_def_t tnet_dns_naptr_def_s =
-{
- sizeof(tnet_dns_naptr_t),
- tnet_dns_naptr_ctor,
- tnet_dns_naptr_dtor,
- tnet_dns_naptr_cmp,
+static const tsk_object_def_t tnet_dns_naptr_def_s = {
+ sizeof(tnet_dns_naptr_t),
+ tnet_dns_naptr_ctor,
+ tnet_dns_naptr_dtor,
+ tnet_dns_naptr_cmp,
};
const tsk_object_def_t *tnet_dns_naptr_def_t = &tnet_dns_naptr_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_naptr.h b/tinyNET/src/dns/tnet_dns_naptr.h
index b960809..f11b970 100755
--- a/tinyNET/src/dns/tnet_dns_naptr.h
+++ b/tinyNET/src/dns/tnet_dns_naptr.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -37,13 +37,12 @@ TNET_BEGIN_DECLS
/** DNS NAPTR Resource Record
*/
-typedef struct tnet_dns_naptr_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_naptr_s {
+ TNET_DECLARE_DNS_RR;
- /* RFC 3403 - 4.1 Packet Format
+ /* RFC 3403 - 4.1 Packet Format
- The packet format for the NAPTR record is as follows
+ The packet format for the NAPTR record is as follows
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
@@ -60,14 +59,14 @@ typedef struct tnet_dns_naptr_s
/ REPLACEMENT /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- <character-string> and <domain-name> as used here are defined in RFC 1035.
- */
- uint16_t order;
- uint16_t preference;
- char* flags;
- char* services;
- char* regexp;
- char* replacement;
+ <character-string> and <domain-name> as used here are defined in RFC 1035.
+ */
+ uint16_t order;
+ uint16_t preference;
+ char* flags;
+ char* services;
+ char* regexp;
+ char* replacement;
}
tnet_dns_naptr_t;
diff --git a/tinyNET/src/dns/tnet_dns_ns.c b/tinyNET/src/dns/tnet_dns_ns.c
index a23426c..64d348b 100755
--- a/tinyNET/src/dns/tnet_dns_ns.c
+++ b/tinyNET/src/dns/tnet_dns_ns.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -37,7 +37,7 @@
*/
tnet_dns_ns_t* tnet_dns_ns_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_ns_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_ns_def_t, name, qclass, ttl, rdlength, data, offset);
}
//=================================================================================================
@@ -45,48 +45,47 @@ tnet_dns_ns_t* tnet_dns_ns_create(const char* name, tnet_dns_qclass_t qclass, ui
//
static tsk_object_t* tnet_dns_ns_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_ns_t *ns = self;
- if(ns){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_ns_t *ns = self;
+ if(ns) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(ns), qtype_ns, qclass);
- TNET_DNS_RR(ns)->name = tsk_strdup(name);
- TNET_DNS_RR(ns)->rdlength = rdlength;
- TNET_DNS_RR(ns)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(ns), qtype_ns, qclass);
+ TNET_DNS_RR(ns)->name = tsk_strdup(name);
+ TNET_DNS_RR(ns)->rdlength = rdlength;
+ TNET_DNS_RR(ns)->ttl = ttl;
- if(rdlength){
- // ==> DESERIALIZATION
- /* NSDNAME */
- tnet_dns_rr_qname_deserialize(data, &(ns->nsdname), &offset);
- }
+ if(rdlength) {
+ // ==> DESERIALIZATION
+ /* NSDNAME */
+ tnet_dns_rr_qname_deserialize(data, &(ns->nsdname), &offset);
+ }
- }
- return self;
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_ns_dtor(tsk_object_t * self)
-{
- tnet_dns_ns_t *ns = self;
- if(ns){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(ns));
+static tsk_object_t* tnet_dns_ns_dtor(tsk_object_t * self)
+{
+ tnet_dns_ns_t *ns = self;
+ if(ns) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(ns));
- TSK_FREE(ns->nsdname);
- }
- return self;
+ TSK_FREE(ns->nsdname);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_ns_def_s =
-{
- sizeof(tnet_dns_ns_t),
- tnet_dns_ns_ctor,
- tnet_dns_ns_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_ns_def_s = {
+ sizeof(tnet_dns_ns_t),
+ tnet_dns_ns_ctor,
+ tnet_dns_ns_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_ns_def_t = &tnet_dns_ns_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_ns.h b/tinyNET/src/dns/tnet_dns_ns.h
index 9a77f26..22b3bf0 100755
--- a/tinyNET/src/dns/tnet_dns_ns.h
+++ b/tinyNET/src/dns/tnet_dns_ns.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,17 +39,16 @@ TNET_BEGIN_DECLS
/** DNS NS Resource Record.
*/
-typedef struct tnet_dns_ns_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_ns_s {
+ TNET_DECLARE_DNS_RR;
- /* RFC 1035 - 3.3.11. NS RDATA format
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ /* RFC 1035 - 3.3.11. NS RDATA format
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/ NSDNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- char* nsdname;
+ */
+ char* nsdname;
}
tnet_dns_ns_t;
diff --git a/tinyNET/src/dns/tnet_dns_opt.c b/tinyNET/src/dns/tnet_dns_opt.c
index dab4fea..9ee2421 100755
--- a/tinyNET/src/dns/tnet_dns_opt.c
+++ b/tinyNET/src/dns/tnet_dns_opt.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -34,7 +34,7 @@
*/
tnet_dns_opt_t* tnet_dns_opt_create(tsk_size_t payload_size)
{
- return tsk_object_new(tnet_dns_opt_def_t, payload_size);
+ return tsk_object_new(tnet_dns_opt_def_t, payload_size);
}
@@ -50,42 +50,41 @@ tnet_dns_opt_t* tnet_dns_opt_create(tsk_size_t payload_size)
//
static tsk_object_t* tnet_dns_opt_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_opt_t *rr_opt = self;
- if(rr_opt){
- uint16_t payload_size = (uint16_t)va_arg(*app, tsk_size_t);
-
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(rr_opt), qtype_opt, qclass_any);
-
- /*
- NAME domain name empty (root domain)
- TYPE u_int16_t OPT
- CLASS u_int16_t sender's UDP payload size
- TTL u_int32_t extended RCODE and flags
- RDLEN u_int16_t describes RDATA
- RDATA octet stream {attribute,value} pairs
-
- */
- TNET_DNS_RR(rr_opt)->qclass = payload_size;
- }
- return self;
+ tnet_dns_opt_t *rr_opt = self;
+ if(rr_opt) {
+ uint16_t payload_size = (uint16_t)va_arg(*app, tsk_size_t);
+
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(rr_opt), qtype_opt, qclass_any);
+
+ /*
+ NAME domain name empty (root domain)
+ TYPE u_int16_t OPT
+ CLASS u_int16_t sender's UDP payload size
+ TTL u_int32_t extended RCODE and flags
+ RDLEN u_int16_t describes RDATA
+ RDATA octet stream {attribute,value} pairs
+
+ */
+ TNET_DNS_RR(rr_opt)->qclass = payload_size;
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_opt_dtor(tsk_object_t * self)
-{
- tnet_dns_opt_t *rr_opt = self;
- if(rr_opt){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(rr_opt));
- }
- return self;
+static tsk_object_t* tnet_dns_opt_dtor(tsk_object_t * self)
+{
+ tnet_dns_opt_t *rr_opt = self;
+ if(rr_opt) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(rr_opt));
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_opt_def_s =
-{
- sizeof(tnet_dns_opt_t),
- tnet_dns_opt_ctor,
- tnet_dns_opt_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_opt_def_s = {
+ sizeof(tnet_dns_opt_t),
+ tnet_dns_opt_ctor,
+ tnet_dns_opt_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_opt_def_t = &tnet_dns_opt_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_opt.h b/tinyNET/src/dns/tnet_dns_opt.h
index 24485b9..ea6bd1d 100755
--- a/tinyNET/src/dns/tnet_dns_opt.h
+++ b/tinyNET/src/dns/tnet_dns_opt.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,9 +38,8 @@ TNET_BEGIN_DECLS
/** DNS OPT Resource Record
*/
-typedef struct tnet_dns_opt_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_opt_s {
+ TNET_DECLARE_DNS_RR;
}
tnet_dns_opt_t;
diff --git a/tinyNET/src/dns/tnet_dns_ptr.c b/tinyNET/src/dns/tnet_dns_ptr.c
index 23b7733..494fd57 100755
--- a/tinyNET/src/dns/tnet_dns_ptr.c
+++ b/tinyNET/src/dns/tnet_dns_ptr.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,7 +39,7 @@
tnet_dns_ptr_t* tnet_dns_ptr_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void*data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_ptr_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_ptr_def_t, name, qclass, ttl, rdlength, data, offset);
}
//=================================================================================================
@@ -47,47 +47,46 @@ tnet_dns_ptr_t* tnet_dns_ptr_create(const char* name, tnet_dns_qclass_t qclass,
//
static tsk_object_t* tnet_dns_ptr_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_ptr_t *ptr = self;
- if(ptr){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_ptr_t *ptr = self;
+ if(ptr) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(ptr), qtype_ptr, qclass);
- TNET_DNS_RR(ptr)->name = tsk_strdup(name);
- TNET_DNS_RR(ptr)->rdlength = rdlength;
- TNET_DNS_RR(ptr)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(ptr), qtype_ptr, qclass);
+ TNET_DNS_RR(ptr)->name = tsk_strdup(name);
+ TNET_DNS_RR(ptr)->rdlength = rdlength;
+ TNET_DNS_RR(ptr)->ttl = ttl;
- if(rdlength){
- // ==> DESERIALIZATION
- /* PTRDNAME */
- tnet_dns_rr_qname_deserialize(data, &(ptr->ptrdname), &offset);
- }
- }
- return self;
+ if(rdlength) {
+ // ==> DESERIALIZATION
+ /* PTRDNAME */
+ tnet_dns_rr_qname_deserialize(data, &(ptr->ptrdname), &offset);
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_ptr_dtor(tsk_object_t * self)
-{
- tnet_dns_ptr_t *ptr = self;
- if(ptr){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(ptr));
+static tsk_object_t* tnet_dns_ptr_dtor(tsk_object_t * self)
+{
+ tnet_dns_ptr_t *ptr = self;
+ if(ptr) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(ptr));
- TSK_FREE(ptr->ptrdname);
- }
- return self;
+ TSK_FREE(ptr->ptrdname);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_ptr_def_s =
-{
- sizeof(tnet_dns_ptr_t),
- tnet_dns_ptr_ctor,
- tnet_dns_ptr_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_ptr_def_s = {
+ sizeof(tnet_dns_ptr_t),
+ tnet_dns_ptr_ctor,
+ tnet_dns_ptr_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_ptr_def_t = &tnet_dns_ptr_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_ptr.h b/tinyNET/src/dns/tnet_dns_ptr.h
index fc2cbdc..778366c 100755
--- a/tinyNET/src/dns/tnet_dns_ptr.h
+++ b/tinyNET/src/dns/tnet_dns_ptr.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,16 +38,15 @@ TNET_BEGIN_DECLS
/** DNS PTR Resource Record
*/
-typedef struct tnet_dns_ptr_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_ptr_s {
+ TNET_DECLARE_DNS_RR;
- /* RFC 1035 - 3.3.12. PTR RDATA format
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ /* RFC 1035 - 3.3.12. PTR RDATA format
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/ PTRDNAME /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- char* ptrdname;
+ */
+ char* ptrdname;
}
tnet_dns_ptr_t;
diff --git a/tinyNET/src/dns/tnet_dns_regexp.c b/tinyNET/src/dns/tnet_dns_regexp.c
index 5cafeb8..ea2f5d8 100755
--- a/tinyNET/src/dns/tnet_dns_regexp.c
+++ b/tinyNET/src/dns/tnet_dns_regexp.c
@@ -2,19 +2,19 @@
/* #line 1 "./ragel/tnet_dns_regexp.rl" */
/*
* Copyright (C) 2010-2015 Mamadou DIOP.
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -46,241 +46,252 @@
*/
char* tnet_dns_regex_parse(const char* e164num, const char* regexp)
{
- char* ret = tsk_null;
- char* prefix = tsk_null;
- const char* tag_start;
- tsk_size_t e164len;
-
- // Ragel
- int cs = 0;
- const char *p = tag_start = regexp;
- const char *pe;
- const char *eof;
-
- TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
-
-/* #line 63 "./src/dns/tnet_dns_regexp.c" */
-static const char _tdns_machine_regexp_actions[] = {
- 0, 1, 0, 1, 1, 1, 2, 2,
- 0, 1, 2, 0, 2, 2, 2, 0,
- 2, 3, 0, 3, 3, 0, 2
-};
-
-static const char _tdns_machine_regexp_key_offsets[] = {
- 0, 0, 1, 2, 5, 6, 7, 8,
- 9, 10, 11, 13, 15, 17, 19, 21,
- 23, 25, 26, 27
-};
-
-static const char _tdns_machine_regexp_trans_keys[] = {
- 33, 94, 40, 46, 92, 40, 46, 42,
- 41, 36, 33, 33, 92, 33, 92, 48,
- 57, 33, 92, 33, 92, 40, 42, 36,
- 40, 40, 105, 0
-};
-
-static const char _tdns_machine_regexp_single_lengths[] = {
- 0, 1, 1, 3, 1, 1, 1, 1,
- 1, 1, 2, 2, 0, 2, 2, 2,
- 2, 1, 1, 0
-};
-
-static const char _tdns_machine_regexp_range_lengths[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 0, 0, 0
-};
-
-static const char _tdns_machine_regexp_index_offsets[] = {
- 0, 0, 2, 4, 8, 10, 12, 14,
- 16, 18, 20, 23, 26, 28, 31, 34,
- 37, 40, 42, 44
-};
-
-static const char _tdns_machine_regexp_trans_targs[] = {
- 2, 0, 3, 0, 5, 15, 17, 4,
- 5, 4, 6, 0, 7, 0, 8, 0,
- 9, 0, 10, 0, 18, 12, 11, 18,
- 12, 11, 13, 0, 18, 0, 14, 18,
- 0, 14, 5, 16, 4, 9, 5, 4,
- 5, 4, 19, 0, 0, 0
-};
-
-static const char _tdns_machine_regexp_trans_actions[] = {
- 0, 0, 0, 0, 7, 1, 0, 1,
- 3, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 10, 10, 10, 13,
- 13, 13, 0, 0, 19, 0, 16, 5,
- 0, 0, 3, 0, 0, 0, 3, 0,
- 7, 1, 0, 0, 0, 0
-};
-
-static const int tdns_machine_regexp_start = 1;
-static const int tdns_machine_regexp_first_final = 18;
-static const int tdns_machine_regexp_error = 0;
-
-static const int tdns_machine_regexp_en_main = 1;
-
-
-/* #line 96 "./ragel/tnet_dns_regexp.rl" */
- TSK_RAGEL_DISABLE_WARNINGS_END()
- (void)(eof);
- (void)(tdns_machine_regexp_first_final);
- (void)(tdns_machine_regexp_error);
- (void)(tdns_machine_regexp_en_main);
-
- if (!e164num) {
- goto bail;
- }
-
- if (!regexp) {
- ret = tsk_strdup(e164num);
- goto bail;
- }
-
- e164len = (tsk_size_t)tsk_strlen(e164num);
- pe = p + tsk_strlen(regexp);
- eof = pe;
-
- TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
-
-/* #line 148 "./src/dns/tnet_dns_regexp.c" */
- {
- cs = tdns_machine_regexp_start;
- }
-
-/* #line 117 "./ragel/tnet_dns_regexp.rl" */
-
-/* #line 155 "./src/dns/tnet_dns_regexp.c" */
- {
- int _klen;
- unsigned int _trans;
- const char *_acts;
- unsigned int _nacts;
- const char *_keys;
-
- if ( p == pe )
- goto _test_eof;
- if ( cs == 0 )
- goto _out;
+ char* ret = tsk_null;
+ char* prefix = tsk_null;
+ const char* tag_start;
+ tsk_size_t e164len;
+
+ // Ragel
+ int cs = 0;
+ const char *p = tag_start = regexp;
+ const char *pe;
+ const char *eof;
+
+ TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
+
+ /* #line 63 "./src/dns/tnet_dns_regexp.c" */
+ static const char _tdns_machine_regexp_actions[] = {
+ 0, 1, 0, 1, 1, 1, 2, 2,
+ 0, 1, 2, 0, 2, 2, 2, 0,
+ 2, 3, 0, 3, 3, 0, 2
+ };
+
+ static const char _tdns_machine_regexp_key_offsets[] = {
+ 0, 0, 1, 2, 5, 6, 7, 8,
+ 9, 10, 11, 13, 15, 17, 19, 21,
+ 23, 25, 26, 27
+ };
+
+ static const char _tdns_machine_regexp_trans_keys[] = {
+ 33, 94, 40, 46, 92, 40, 46, 42,
+ 41, 36, 33, 33, 92, 33, 92, 48,
+ 57, 33, 92, 33, 92, 40, 42, 36,
+ 40, 40, 105, 0
+ };
+
+ static const char _tdns_machine_regexp_single_lengths[] = {
+ 0, 1, 1, 3, 1, 1, 1, 1,
+ 1, 1, 2, 2, 0, 2, 2, 2,
+ 2, 1, 1, 0
+ };
+
+ static const char _tdns_machine_regexp_range_lengths[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0,
+ 0, 0, 0, 0
+ };
+
+ static const char _tdns_machine_regexp_index_offsets[] = {
+ 0, 0, 2, 4, 8, 10, 12, 14,
+ 16, 18, 20, 23, 26, 28, 31, 34,
+ 37, 40, 42, 44
+ };
+
+ static const char _tdns_machine_regexp_trans_targs[] = {
+ 2, 0, 3, 0, 5, 15, 17, 4,
+ 5, 4, 6, 0, 7, 0, 8, 0,
+ 9, 0, 10, 0, 18, 12, 11, 18,
+ 12, 11, 13, 0, 18, 0, 14, 18,
+ 0, 14, 5, 16, 4, 9, 5, 4,
+ 5, 4, 19, 0, 0, 0
+ };
+
+ static const char _tdns_machine_regexp_trans_actions[] = {
+ 0, 0, 0, 0, 7, 1, 0, 1,
+ 3, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 10, 10, 10, 13,
+ 13, 13, 0, 0, 19, 0, 16, 5,
+ 0, 0, 3, 0, 0, 0, 3, 0,
+ 7, 1, 0, 0, 0, 0
+ };
+
+ static const int tdns_machine_regexp_start = 1;
+ static const int tdns_machine_regexp_first_final = 18;
+ static const int tdns_machine_regexp_error = 0;
+
+ static const int tdns_machine_regexp_en_main = 1;
+
+
+ /* #line 96 "./ragel/tnet_dns_regexp.rl" */
+ TSK_RAGEL_DISABLE_WARNINGS_END()
+ (void)(eof);
+ (void)(tdns_machine_regexp_first_final);
+ (void)(tdns_machine_regexp_error);
+ (void)(tdns_machine_regexp_en_main);
+
+ if (!e164num) {
+ goto bail;
+ }
+
+ if (!regexp) {
+ ret = tsk_strdup(e164num);
+ goto bail;
+ }
+
+ e164len = (tsk_size_t)tsk_strlen(e164num);
+ pe = p + tsk_strlen(regexp);
+ eof = pe;
+
+ TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
+
+ /* #line 148 "./src/dns/tnet_dns_regexp.c" */
+ {
+ cs = tdns_machine_regexp_start;
+ }
+
+ /* #line 117 "./ragel/tnet_dns_regexp.rl" */
+
+ /* #line 155 "./src/dns/tnet_dns_regexp.c" */
+ {
+ int _klen;
+ unsigned int _trans;
+ const char *_acts;
+ unsigned int _nacts;
+ const char *_keys;
+
+ if ( p == pe ) {
+ goto _test_eof;
+ }
+ if ( cs == 0 ) {
+ goto _out;
+ }
_resume:
- _keys = _tdns_machine_regexp_trans_keys + _tdns_machine_regexp_key_offsets[cs];
- _trans = _tdns_machine_regexp_index_offsets[cs];
-
- _klen = _tdns_machine_regexp_single_lengths[cs];
- if ( _klen > 0 ) {
- const char *_lower = _keys;
- const char *_mid;
- const char *_upper = _keys + _klen - 1;
- while (1) {
- if ( _upper < _lower )
- break;
-
- _mid = _lower + ((_upper-_lower) >> 1);
- if ( (*p) < *_mid )
- _upper = _mid - 1;
- else if ( (*p) > *_mid )
- _lower = _mid + 1;
- else {
- _trans += (_mid - _keys);
- goto _match;
- }
- }
- _keys += _klen;
- _trans += _klen;
- }
-
- _klen = _tdns_machine_regexp_range_lengths[cs];
- if ( _klen > 0 ) {
- const char *_lower = _keys;
- const char *_mid;
- const char *_upper = _keys + (_klen<<1) - 2;
- while (1) {
- if ( _upper < _lower )
- break;
-
- _mid = _lower + (((_upper-_lower) >> 1) & ~1);
- if ( (*p) < _mid[0] )
- _upper = _mid - 2;
- else if ( (*p) > _mid[1] )
- _lower = _mid + 2;
- else {
- _trans += ((_mid - _keys)>>1);
- goto _match;
- }
- }
- _trans += _klen;
- }
+ _keys = _tdns_machine_regexp_trans_keys + _tdns_machine_regexp_key_offsets[cs];
+ _trans = _tdns_machine_regexp_index_offsets[cs];
+
+ _klen = _tdns_machine_regexp_single_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + _klen - 1;
+ while (1) {
+ if ( _upper < _lower ) {
+ break;
+ }
+
+ _mid = _lower + ((_upper-_lower) >> 1);
+ if ( (*p) < *_mid ) {
+ _upper = _mid - 1;
+ }
+ else if ( (*p) > *_mid ) {
+ _lower = _mid + 1;
+ }
+ else {
+ _trans += (_mid - _keys);
+ goto _match;
+ }
+ }
+ _keys += _klen;
+ _trans += _klen;
+ }
+
+ _klen = _tdns_machine_regexp_range_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + (_klen<<1) - 2;
+ while (1) {
+ if ( _upper < _lower ) {
+ break;
+ }
+
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+ if ( (*p) < _mid[0] ) {
+ _upper = _mid - 2;
+ }
+ else if ( (*p) > _mid[1] ) {
+ _lower = _mid + 2;
+ }
+ else {
+ _trans += ((_mid - _keys)>>1);
+ goto _match;
+ }
+ }
+ _trans += _klen;
+ }
_match:
- cs = _tdns_machine_regexp_trans_targs[_trans];
-
- if ( _tdns_machine_regexp_trans_actions[_trans] == 0 )
- goto _again;
-
- _acts = _tdns_machine_regexp_actions + _tdns_machine_regexp_trans_actions[_trans];
- _nacts = (unsigned int) *_acts++;
- while ( _nacts-- > 0 )
- {
- switch ( *_acts++ )
- {
- case 0:
-/* #line 36 "./ragel/tnet_dns_regexp.rl" */
- {
- tag_start = p;
- }
- break;
- case 1:
-/* #line 40 "./ragel/tnet_dns_regexp.rl" */
- {
- TSK_PARSER_SET_STRING(prefix);
- }
- break;
- case 2:
-/* #line 44 "./ragel/tnet_dns_regexp.rl" */
- {
- int len = (int)(p - tag_start);
- if (len) {
- tsk_strncat(&ret, tag_start, len);
- }
- }
- break;
- case 3:
-/* #line 51 "./ragel/tnet_dns_regexp.rl" */
- {
- if (prefix) {
- int prefixlen = (int)tsk_strlen(prefix);
- tsk_strncat(&ret, e164num + prefixlen, (e164len - prefixlen));
- }
- }
- break;
-/* #line 258 "./src/dns/tnet_dns_regexp.c" */
- }
- }
+ cs = _tdns_machine_regexp_trans_targs[_trans];
+
+ if ( _tdns_machine_regexp_trans_actions[_trans] == 0 ) {
+ goto _again;
+ }
+
+ _acts = _tdns_machine_regexp_actions + _tdns_machine_regexp_trans_actions[_trans];
+ _nacts = (unsigned int) *_acts++;
+ while ( _nacts-- > 0 ) {
+ switch ( *_acts++ ) {
+ case 0:
+ /* #line 36 "./ragel/tnet_dns_regexp.rl" */
+ {
+ tag_start = p;
+ }
+ break;
+ case 1:
+ /* #line 40 "./ragel/tnet_dns_regexp.rl" */
+ {
+ TSK_PARSER_SET_STRING(prefix);
+ }
+ break;
+ case 2:
+ /* #line 44 "./ragel/tnet_dns_regexp.rl" */
+ {
+ int len = (int)(p - tag_start);
+ if (len) {
+ tsk_strncat(&ret, tag_start, len);
+ }
+ }
+ break;
+ case 3:
+ /* #line 51 "./ragel/tnet_dns_regexp.rl" */
+ {
+ if (prefix) {
+ int prefixlen = (int)tsk_strlen(prefix);
+ tsk_strncat(&ret, e164num + prefixlen, (e164len - prefixlen));
+ }
+ }
+ break;
+ /* #line 258 "./src/dns/tnet_dns_regexp.c" */
+ }
+ }
_again:
- if ( cs == 0 )
- goto _out;
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- _out: {}
- }
-
-/* #line 118 "./ragel/tnet_dns_regexp.rl" */
- TSK_RAGEL_DISABLE_WARNINGS_END()
-
- if (cs <
-/* #line 275 "./src/dns/tnet_dns_regexp.c" */
-18
-/* #line 120 "./ragel/tnet_dns_regexp.rl" */
- ){
- TSK_DEBUG_ERROR("regexp substitition failed.");
- TSK_FREE(ret);
- }
+ if ( cs == 0 ) {
+ goto _out;
+ }
+ if ( ++p != pe ) {
+ goto _resume;
+ }
+_test_eof: {
+ }
+_out: {
+ }
+ }
+
+ /* #line 118 "./ragel/tnet_dns_regexp.rl" */
+ TSK_RAGEL_DISABLE_WARNINGS_END()
+
+ if (cs <
+ /* #line 275 "./src/dns/tnet_dns_regexp.c" */
+ 18
+ /* #line 120 "./ragel/tnet_dns_regexp.rl" */
+ ) {
+ TSK_DEBUG_ERROR("regexp substitition failed.");
+ TSK_FREE(ret);
+ }
bail:
- TSK_FREE(prefix);
-
- return ret;
+ TSK_FREE(prefix);
+
+ return ret;
}
diff --git a/tinyNET/src/dns/tnet_dns_regexp.h b/tinyNET/src/dns/tnet_dns_regexp.h
index d40abce..6fab026 100755
--- a/tinyNET/src/dns/tnet_dns_regexp.h
+++ b/tinyNET/src/dns/tnet_dns_regexp.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/dns/tnet_dns_resolvconf.c b/tinyNET/src/dns/tnet_dns_resolvconf.c
index a4a0fbf..b77ba8f 100755
--- a/tinyNET/src/dns/tnet_dns_resolvconf.c
+++ b/tinyNET/src/dns/tnet_dns_resolvconf.c
@@ -9,12 +9,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -50,265 +50,273 @@
*/
tnet_addresses_L_t * tnet_dns_resolvconf_parse(const char* path)
{
- tnet_addresses_L_t* servers = tsk_null;
- tnet_ip_t ip;
- const char* fullpath = path;
- const char* tag_start = tsk_null;
- FILE* fd;
- char* buf = tsk_null;
-
- // Ragel
- int cs = 0;
- const char *p;
- const char *pe;
- const char *eof;
-
- TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
-
-/* #line 69 "./src/dns/tnet_dns_resolvconf.c" */
-static const char _tdns_machine_resolvconf_actions[] = {
- 0, 1, 0, 1, 1
-};
-
-static const char _tdns_machine_resolvconf_key_offsets[] = {
- 0, 7, 8, 9, 12, 15, 15, 22,
- 24, 27, 30, 33, 36, 39, 42, 45,
- 48, 51, 52, 53, 56
-};
-
-static const char _tdns_machine_resolvconf_trans_keys[] = {
- 10, 13, 32, 35, 59, 78, 110, 32,
- 32, 10, 13, 32, 10, 13, 32, 10,
- 13, 32, 35, 59, 78, 110, 10, 13,
- 32, 65, 97, 32, 77, 109, 32, 69,
- 101, 32, 83, 115, 32, 69, 101, 32,
- 82, 114, 32, 86, 118, 32, 69, 101,
- 32, 82, 114, 32, 32, 10, 13, 32,
- 32, 35, 59, 78, 110, 0
-};
-
-static const char _tdns_machine_resolvconf_single_lengths[] = {
- 7, 1, 1, 3, 3, 0, 7, 2,
- 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 1, 1, 3, 5
-};
-
-static const char _tdns_machine_resolvconf_range_lengths[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0
-};
-
-static const char _tdns_machine_resolvconf_index_offsets[] = {
- 0, 8, 10, 12, 16, 20, 21, 29,
- 32, 36, 40, 44, 48, 52, 56, 60,
- 64, 68, 70, 72, 76
-};
-
-static const char _tdns_machine_resolvconf_indicies[] = {
- 1, 1, 2, 3, 3, 4, 4, 0,
- 5, 0, 5, 6, 7, 7, 8, 6,
- 7, 7, 8, 9, 9, 1, 1, 5,
- 3, 3, 4, 4, 0, 7, 7, 3,
- 5, 10, 10, 0, 5, 11, 11, 0,
- 5, 12, 12, 0, 5, 13, 13, 0,
- 5, 14, 14, 0, 5, 15, 15, 0,
- 5, 16, 16, 0, 5, 17, 17, 0,
- 5, 18, 18, 0, 19, 0, 19, 20,
- 22, 22, 23, 21, 2, 3, 3, 4,
- 4, 0, 0
-};
-
-static const char _tdns_machine_resolvconf_trans_targs[] = {
- 1, 6, 20, 7, 8, 2, 3, 0,
- 4, 5, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 19, 0, 4
-};
-
-static const char _tdns_machine_resolvconf_trans_actions[] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 1, 0, 3, 3
-};
-
-static const int tdns_machine_resolvconf_start = 0;
-static const int tdns_machine_resolvconf_first_final = 0;
-static const int tdns_machine_resolvconf_error = -1;
-
-static const int tdns_machine_resolvconf_en_main = 0;
-
-
-/* #line 101 "./ragel/tnet_dns_resolvconf.rl" */
- TSK_RAGEL_DISABLE_WARNINGS_END()
- (void)(eof);
- (void)(tdns_machine_resolvconf_first_final);
- (void)(tdns_machine_resolvconf_error);
- (void)(tdns_machine_resolvconf_en_main);
-
- if(tsk_strnullORempty(fullpath)){
- fullpath = TNET_RESOLV_CONF_PATH;
- }
-
- /* Open the file and read all data */
- if((fd = fopen(fullpath, "r"))){
- long len;
- fseek(fd, 0L, SEEK_END);
- len = ftell(fd);
- fseek(fd, 0L, SEEK_SET);
- if (!(buf = (char*)tsk_calloc(len + 1, 1))) {
- TSK_DEBUG_ERROR("Failed to allocate buffer with size = %ld", (len + 1));
- goto bail;
- }
- fread(buf, 1, len, fd);
- p = &buf[0];
- pe = p + len + 1/*hack*/;
- eof = pe;
- fclose(fd);
-
- buf[len] = '\n'; // hack to have perfect lines
-
- servers = tsk_list_create();
- }
- else {
+ tnet_addresses_L_t* servers = tsk_null;
+ tnet_ip_t ip;
+ const char* fullpath = path;
+ const char* tag_start = tsk_null;
+ FILE* fd;
+ char* buf = tsk_null;
+
+ // Ragel
+ int cs = 0;
+ const char *p;
+ const char *pe;
+ const char *eof;
+
+ TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
+
+ /* #line 69 "./src/dns/tnet_dns_resolvconf.c" */
+ static const char _tdns_machine_resolvconf_actions[] = {
+ 0, 1, 0, 1, 1
+ };
+
+ static const char _tdns_machine_resolvconf_key_offsets[] = {
+ 0, 7, 8, 9, 12, 15, 15, 22,
+ 24, 27, 30, 33, 36, 39, 42, 45,
+ 48, 51, 52, 53, 56
+ };
+
+ static const char _tdns_machine_resolvconf_trans_keys[] = {
+ 10, 13, 32, 35, 59, 78, 110, 32,
+ 32, 10, 13, 32, 10, 13, 32, 10,
+ 13, 32, 35, 59, 78, 110, 10, 13,
+ 32, 65, 97, 32, 77, 109, 32, 69,
+ 101, 32, 83, 115, 32, 69, 101, 32,
+ 82, 114, 32, 86, 118, 32, 69, 101,
+ 32, 82, 114, 32, 32, 10, 13, 32,
+ 32, 35, 59, 78, 110, 0
+ };
+
+ static const char _tdns_machine_resolvconf_single_lengths[] = {
+ 7, 1, 1, 3, 3, 0, 7, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 1, 1, 3, 5
+ };
+
+ static const char _tdns_machine_resolvconf_range_lengths[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0
+ };
+
+ static const char _tdns_machine_resolvconf_index_offsets[] = {
+ 0, 8, 10, 12, 16, 20, 21, 29,
+ 32, 36, 40, 44, 48, 52, 56, 60,
+ 64, 68, 70, 72, 76
+ };
+
+ static const char _tdns_machine_resolvconf_indicies[] = {
+ 1, 1, 2, 3, 3, 4, 4, 0,
+ 5, 0, 5, 6, 7, 7, 8, 6,
+ 7, 7, 8, 9, 9, 1, 1, 5,
+ 3, 3, 4, 4, 0, 7, 7, 3,
+ 5, 10, 10, 0, 5, 11, 11, 0,
+ 5, 12, 12, 0, 5, 13, 13, 0,
+ 5, 14, 14, 0, 5, 15, 15, 0,
+ 5, 16, 16, 0, 5, 17, 17, 0,
+ 5, 18, 18, 0, 19, 0, 19, 20,
+ 22, 22, 23, 21, 2, 3, 3, 4,
+ 4, 0, 0
+ };
+
+ static const char _tdns_machine_resolvconf_trans_targs[] = {
+ 1, 6, 20, 7, 8, 2, 3, 0,
+ 4, 5, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 19, 0, 4
+ };
+
+ static const char _tdns_machine_resolvconf_trans_actions[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 3, 3
+ };
+
+ static const int tdns_machine_resolvconf_start = 0;
+ static const int tdns_machine_resolvconf_first_final = 0;
+ static const int tdns_machine_resolvconf_error = -1;
+
+ static const int tdns_machine_resolvconf_en_main = 0;
+
+
+ /* #line 101 "./ragel/tnet_dns_resolvconf.rl" */
+ TSK_RAGEL_DISABLE_WARNINGS_END()
+ (void)(eof);
+ (void)(tdns_machine_resolvconf_first_final);
+ (void)(tdns_machine_resolvconf_error);
+ (void)(tdns_machine_resolvconf_en_main);
+
+ if(tsk_strnullORempty(fullpath)) {
+ fullpath = TNET_RESOLV_CONF_PATH;
+ }
+
+ /* Open the file and read all data */
+ if((fd = fopen(fullpath, "r"))) {
+ long len;
+ fseek(fd, 0L, SEEK_END);
+ len = ftell(fd);
+ fseek(fd, 0L, SEEK_SET);
+ if (!(buf = (char*)tsk_calloc(len + 1, 1))) {
+ TSK_DEBUG_ERROR("Failed to allocate buffer with size = %ld", (len + 1));
+ goto bail;
+ }
+ fread(buf, 1, len, fd);
+ p = &buf[0];
+ pe = p + len + 1/*hack*/;
+ eof = pe;
+ fclose(fd);
+
+ buf[len] = '\n'; // hack to have perfect lines
+
+ servers = tsk_list_create();
+ }
+ else {
#if ANDROID || defined(__APPLE__) /* TARGET_OS_IPHONE not defined for bsd libraries */
- TSK_DEBUG_INFO("Failed to open [%s]. But don't panic, we have detected that you are using Google Android/iOS Systems.\n"
- "You should look at the Progammer's Guide for more information.\n If you are not using DNS functions, don't worry about this warning.",
- fullpath);
+ TSK_DEBUG_INFO("Failed to open [%s]. But don't panic, we have detected that you are using Google Android/iOS Systems.\n"
+ "You should look at the Progammer's Guide for more information.\n If you are not using DNS functions, don't worry about this warning.",
+ fullpath);
#else
- TSK_DEBUG_ERROR("Failed to open %s.", fullpath);
+ TSK_DEBUG_ERROR("Failed to open %s.", fullpath);
#endif
- goto bail;
- }
-
- TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
-
-/* #line 186 "./src/dns/tnet_dns_resolvconf.c" */
- {
- cs = tdns_machine_resolvconf_start;
- }
-
-/* #line 144 "./ragel/tnet_dns_resolvconf.rl" */
-
-/* #line 193 "./src/dns/tnet_dns_resolvconf.c" */
- {
- int _klen;
- unsigned int _trans;
- const char *_acts;
- unsigned int _nacts;
- const char *_keys;
-
- if ( p == pe )
- goto _test_eof;
+ goto bail;
+ }
+
+ TSK_RAGEL_DISABLE_WARNINGS_BEGIN()
+
+ /* #line 186 "./src/dns/tnet_dns_resolvconf.c" */
+ {
+ cs = tdns_machine_resolvconf_start;
+ }
+
+ /* #line 144 "./ragel/tnet_dns_resolvconf.rl" */
+
+ /* #line 193 "./src/dns/tnet_dns_resolvconf.c" */
+ {
+ int _klen;
+ unsigned int _trans;
+ const char *_acts;
+ unsigned int _nacts;
+ const char *_keys;
+
+ if ( p == pe ) {
+ goto _test_eof;
+ }
_resume:
- _keys = _tdns_machine_resolvconf_trans_keys + _tdns_machine_resolvconf_key_offsets[cs];
- _trans = _tdns_machine_resolvconf_index_offsets[cs];
-
- _klen = _tdns_machine_resolvconf_single_lengths[cs];
- if ( _klen > 0 ) {
- const char *_lower = _keys;
- const char *_mid;
- const char *_upper = _keys + _klen - 1;
- while (1) {
- if ( _upper < _lower )
- break;
-
- _mid = _lower + ((_upper-_lower) >> 1);
- if ( (*p) < *_mid )
- _upper = _mid - 1;
- else if ( (*p) > *_mid )
- _lower = _mid + 1;
- else {
- _trans += (_mid - _keys);
- goto _match;
- }
- }
- _keys += _klen;
- _trans += _klen;
- }
-
- _klen = _tdns_machine_resolvconf_range_lengths[cs];
- if ( _klen > 0 ) {
- const char *_lower = _keys;
- const char *_mid;
- const char *_upper = _keys + (_klen<<1) - 2;
- while (1) {
- if ( _upper < _lower )
- break;
-
- _mid = _lower + (((_upper-_lower) >> 1) & ~1);
- if ( (*p) < _mid[0] )
- _upper = _mid - 2;
- else if ( (*p) > _mid[1] )
- _lower = _mid + 2;
- else {
- _trans += ((_mid - _keys)>>1);
- goto _match;
- }
- }
- _trans += _klen;
- }
+ _keys = _tdns_machine_resolvconf_trans_keys + _tdns_machine_resolvconf_key_offsets[cs];
+ _trans = _tdns_machine_resolvconf_index_offsets[cs];
+
+ _klen = _tdns_machine_resolvconf_single_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + _klen - 1;
+ while (1) {
+ if ( _upper < _lower ) {
+ break;
+ }
+
+ _mid = _lower + ((_upper-_lower) >> 1);
+ if ( (*p) < *_mid ) {
+ _upper = _mid - 1;
+ }
+ else if ( (*p) > *_mid ) {
+ _lower = _mid + 1;
+ }
+ else {
+ _trans += (_mid - _keys);
+ goto _match;
+ }
+ }
+ _keys += _klen;
+ _trans += _klen;
+ }
+
+ _klen = _tdns_machine_resolvconf_range_lengths[cs];
+ if ( _klen > 0 ) {
+ const char *_lower = _keys;
+ const char *_mid;
+ const char *_upper = _keys + (_klen<<1) - 2;
+ while (1) {
+ if ( _upper < _lower ) {
+ break;
+ }
+
+ _mid = _lower + (((_upper-_lower) >> 1) & ~1);
+ if ( (*p) < _mid[0] ) {
+ _upper = _mid - 2;
+ }
+ else if ( (*p) > _mid[1] ) {
+ _lower = _mid + 2;
+ }
+ else {
+ _trans += ((_mid - _keys)>>1);
+ goto _match;
+ }
+ }
+ _trans += _klen;
+ }
_match:
- _trans = _tdns_machine_resolvconf_indicies[_trans];
- cs = _tdns_machine_resolvconf_trans_targs[_trans];
-
- if ( _tdns_machine_resolvconf_trans_actions[_trans] == 0 )
- goto _again;
-
- _acts = _tdns_machine_resolvconf_actions + _tdns_machine_resolvconf_trans_actions[_trans];
- _nacts = (unsigned int) *_acts++;
- while ( _nacts-- > 0 )
- {
- switch ( *_acts++ )
- {
- case 0:
-/* #line 41 "./ragel/tnet_dns_resolvconf.rl" */
- {
- tag_start = p;
- }
- break;
- case 1:
-/* #line 45 "./ragel/tnet_dns_resolvconf.rl" */
- {
- int len = (int)(p - tag_start);
- if(len && len<=sizeof(ip)){
- tnet_address_t *address;
- memset(ip, '\0', sizeof(ip));
- memcpy(ip, tag_start, len);
- TSK_DEBUG_INFO("Adding DNS server = %s:%d", ip, TNET_DNS_SERVER_PORT_DEFAULT);
-
- address = tnet_address_create(ip);
- address->family = tnet_get_family(ip, TNET_DNS_SERVER_PORT_DEFAULT);
- address->dnsserver = 1;
- tsk_list_push_ascending_data(servers, (void**)&address);
- }
- }
- break;
-/* #line 288 "./src/dns/tnet_dns_resolvconf.c" */
- }
- }
+ _trans = _tdns_machine_resolvconf_indicies[_trans];
+ cs = _tdns_machine_resolvconf_trans_targs[_trans];
+
+ if ( _tdns_machine_resolvconf_trans_actions[_trans] == 0 ) {
+ goto _again;
+ }
+
+ _acts = _tdns_machine_resolvconf_actions + _tdns_machine_resolvconf_trans_actions[_trans];
+ _nacts = (unsigned int) *_acts++;
+ while ( _nacts-- > 0 ) {
+ switch ( *_acts++ ) {
+ case 0:
+ /* #line 41 "./ragel/tnet_dns_resolvconf.rl" */
+ {
+ tag_start = p;
+ }
+ break;
+ case 1:
+ /* #line 45 "./ragel/tnet_dns_resolvconf.rl" */
+ {
+ int len = (int)(p - tag_start);
+ if(len && len<=sizeof(ip)) {
+ tnet_address_t *address;
+ memset(ip, '\0', sizeof(ip));
+ memcpy(ip, tag_start, len);
+ TSK_DEBUG_INFO("Adding DNS server = %s:%d", ip, TNET_DNS_SERVER_PORT_DEFAULT);
+
+ address = tnet_address_create(ip);
+ address->family = tnet_get_family(ip, TNET_DNS_SERVER_PORT_DEFAULT);
+ address->dnsserver = 1;
+ tsk_list_push_ascending_data(servers, (void**)&address);
+ }
+ }
+ break;
+ /* #line 288 "./src/dns/tnet_dns_resolvconf.c" */
+ }
+ }
_again:
- if ( ++p != pe )
- goto _resume;
- _test_eof: {}
- }
-
-/* #line 145 "./ragel/tnet_dns_resolvconf.rl" */
- TSK_RAGEL_DISABLE_WARNINGS_END()
-
- if (cs <
-/* #line 302 "./src/dns/tnet_dns_resolvconf.c" */
-0
-/* #line 147 "./ragel/tnet_dns_resolvconf.rl" */
- ) {
- TSK_DEBUG_ERROR("Failed to parse %s.", fullpath);
- TSK_OBJECT_SAFE_FREE(servers);
- }
+ if ( ++p != pe ) {
+ goto _resume;
+ }
+_test_eof: {
+ }
+ }
+
+ /* #line 145 "./ragel/tnet_dns_resolvconf.rl" */
+ TSK_RAGEL_DISABLE_WARNINGS_END()
+
+ if (cs <
+ /* #line 302 "./src/dns/tnet_dns_resolvconf.c" */
+ 0
+ /* #line 147 "./ragel/tnet_dns_resolvconf.rl" */
+ ) {
+ TSK_DEBUG_ERROR("Failed to parse %s.", fullpath);
+ TSK_OBJECT_SAFE_FREE(servers);
+ }
bail:
- TSK_FREE(buf);
- return servers;
+ TSK_FREE(buf);
+ return servers;
}
diff --git a/tinyNET/src/dns/tnet_dns_resolvconf.h b/tinyNET/src/dns/tnet_dns_resolvconf.h
index 5290c41..53c5b70 100755
--- a/tinyNET/src/dns/tnet_dns_resolvconf.h
+++ b/tinyNET/src/dns/tnet_dns_resolvconf.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/dns/tnet_dns_rr.c b/tinyNET/src/dns/tnet_dns_rr.c
index b74a31d..eb5125a 100755
--- a/tinyNET/src/dns/tnet_dns_rr.c
+++ b/tinyNET/src/dns/tnet_dns_rr.c
@@ -50,7 +50,7 @@
tnet_dns_rr_t* tnet_dns_rr_create()
{
- return tsk_object_new(tnet_dns_rr_def_t);
+ return tsk_object_new(tnet_dns_rr_def_t);
}
/** Initializes any DNS RR (either NAPTR or SRV ...).
@@ -61,17 +61,17 @@ tnet_dns_rr_t* tnet_dns_rr_create()
*/
int tnet_dns_rr_init(tnet_dns_rr_t *rr, tnet_dns_qtype_t qtype, tnet_dns_qclass_t qclass)
{
- if (rr){
- if (!rr->initialized){
- rr->qtype = qtype;
- rr->qclass = qclass;
-
- rr->initialized = tsk_true;
- return 0;
- }
- return -2;
- }
- return -1;
+ if (rr) {
+ if (!rr->initialized) {
+ rr->qtype = qtype;
+ rr->qclass = qclass;
+
+ rr->initialized = tsk_true;
+ return 0;
+ }
+ return -2;
+ }
+ return -1;
}
/** Deinitializes any DNS RR (either NAPTR or SRV ...).
@@ -80,79 +80,79 @@ int tnet_dns_rr_init(tnet_dns_rr_t *rr, tnet_dns_qtype_t qtype, tnet_dns_qclass_
*/
int tnet_dns_rr_deinit(tnet_dns_rr_t *rr)
{
- if (rr){
- if (rr->initialized){
- TSK_FREE(rr->name);
- TSK_FREE(rr->rpdata);
-
- rr->initialized = tsk_false;
- return 0;
- }
- return -2;
- }
- return -1;
+ if (rr) {
+ if (rr->initialized) {
+ TSK_FREE(rr->name);
+ TSK_FREE(rr->rpdata);
+
+ rr->initialized = tsk_false;
+ return 0;
+ }
+ return -2;
+ }
+ return -1;
}
/** Deserialize <character-string>.
*/
int tnet_dns_rr_charstring_deserialize(const void* data, char** charstring, tsk_size_t *offset)
{
- /* RFC 1035 - 3.3. Standard RRs
- <character-string> is a single length octet followed by that number of characters.
- <character-string> is treated as binary information, and can be up to 256 characters in
- length (including the length octet).
- */
- uint8_t* dataPtr = (((uint8_t*)data) + *offset);
- uint8_t length = *dataPtr;
-
- *charstring = tsk_strndup((const char*)(dataPtr + 1), length);
- *offset += (1 + length);
-
- return 0;
+ /* RFC 1035 - 3.3. Standard RRs
+ <character-string> is a single length octet followed by that number of characters.
+ <character-string> is treated as binary information, and can be up to 256 characters in
+ length (including the length octet).
+ */
+ uint8_t* dataPtr = (((uint8_t*)data) + *offset);
+ uint8_t length = *dataPtr;
+
+ *charstring = tsk_strndup((const char*)(dataPtr + 1), length);
+ *offset += (1 + length);
+
+ return 0;
}
/** Deserializes a QName.
*/
int tnet_dns_rr_qname_deserialize(const void* data, char** name, tsk_size_t *offset)
{
- /* RFC 1035 - 4.1.4. Message compression
+ /* RFC 1035 - 4.1.4. Message compression
- The pointer takes the form of a two octet sequence:
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- | 1 1| OFFSET |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- uint8_t* dataPtr = (((uint8_t*)data) + *offset);
- unsigned usingPtr = 0; /* Do not change. */
+ The pointer takes the form of a two octet sequence:
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | 1 1| OFFSET |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ */
+ uint8_t* dataPtr = (((uint8_t*)data) + *offset);
+ unsigned usingPtr = 0; /* Do not change. */
- while (*dataPtr){
- usingPtr = ((*dataPtr & 0xC0) == 0xC0);
+ while (*dataPtr) {
+ usingPtr = ((*dataPtr & 0xC0) == 0xC0);
- if (usingPtr){
- tsk_size_t ptr_offset = (*dataPtr & 0x3F);
- ptr_offset = ptr_offset << 8 | *(dataPtr + 1);
+ if (usingPtr) {
+ tsk_size_t ptr_offset = (*dataPtr & 0x3F);
+ ptr_offset = ptr_offset << 8 | *(dataPtr + 1);
- *offset += 2;
- return tnet_dns_rr_qname_deserialize(data, name, &ptr_offset);
- }
- else{
- uint8_t length;
+ *offset += 2;
+ return tnet_dns_rr_qname_deserialize(data, name, &ptr_offset);
+ }
+ else {
+ uint8_t length;
- if (*name){
- tsk_strcat(name, ".");
- }
+ if (*name) {
+ tsk_strcat(name, ".");
+ }
- length = *dataPtr;
- *offset += 1, dataPtr++;
+ length = *dataPtr;
+ *offset += 1, dataPtr++;
- tsk_strncat(name, (const char*)dataPtr, length);
- *offset += length, dataPtr += length;
- }
- }
+ tsk_strncat(name, (const char*)dataPtr, length);
+ *offset += length, dataPtr += length;
+ }
+ }
- *offset += 1;
+ *offset += 1;
- return 0;
+ return 0;
}
//int tnet_dns_rr_qname_deserialize(const void* data, tsk_size_t size, char** name, tsk_size_t *offset)
@@ -179,7 +179,7 @@ int tnet_dns_rr_qname_deserialize(const void* data, char** name, tsk_size_t *off
// uint16_t ptr_offset = (*dataPtr & 0x3F);
// ptr_offset = ptr_offset << 8 | *(dataPtr+1);
// Ptr = ((uint8_t*)data) + ptr_offset;
-//
+//
// tnet_qname_label_parse(Ptr, (dataEnd - Ptr), name, &islast);
// *offset += 2, dataPtr += 2;
// }
@@ -199,221 +199,208 @@ int tnet_dns_rr_qname_deserialize(const void* data, char** name, tsk_size_t *off
*/
int tnet_dns_rr_qname_serialize(const char* qname, tsk_buffer_t* output)
{
- /*
- QNAME a domain name represented as a sequence of labels, where
- each label consists of a length octet followed by that
- number of octets. The domain name terminates with the
- zero length octet for the null label of the root. Note
- that this field may be an odd number of octets; no
- padding is used.
-
- Example: "doubango.com" ==> 8doubango3comNULL
- */
- static uint8_t null = 0;
-
- if (qname){
- char* saveptr;
- char* _qname = tsk_strdup(qname);
- char* label = tsk_strtok_r(_qname, ".", &saveptr);
-
- while (label){
- uint8_t length = (uint8_t)tsk_strlen(label);
- tsk_buffer_append(output, &length, 1);
- tsk_buffer_append(output, label, tsk_strlen(label));
-
- label = tsk_strtok_r(tsk_null, ".", &saveptr);
- }
-
- TSK_FREE(_qname);
- }
-
- /* terminates domain name */
- tsk_buffer_append(output, &null, 1);
-
- return 0;
+ /*
+ QNAME a domain name represented as a sequence of labels, where
+ each label consists of a length octet followed by that
+ number of octets. The domain name terminates with the
+ zero length octet for the null label of the root. Note
+ that this field may be an odd number of octets; no
+ padding is used.
+
+ Example: "doubango.com" ==> 8doubango3comNULL
+ */
+ static uint8_t null = 0;
+
+ if (qname) {
+ char* saveptr;
+ char* _qname = tsk_strdup(qname);
+ char* label = tsk_strtok_r(_qname, ".", &saveptr);
+
+ while (label) {
+ uint8_t length = (uint8_t)tsk_strlen(label);
+ tsk_buffer_append(output, &length, 1);
+ tsk_buffer_append(output, label, tsk_strlen(label));
+
+ label = tsk_strtok_r(tsk_null, ".", &saveptr);
+ }
+
+ TSK_FREE(_qname);
+ }
+
+ /* terminates domain name */
+ tsk_buffer_append(output, &null, 1);
+
+ return 0;
}
/** Deserializes a DNS RR.
*/
tnet_dns_rr_t* tnet_dns_rr_deserialize(const void* data, tsk_size_t size, tsk_size_t* offset)
{
- tnet_dns_rr_t *rr = tsk_null;
- uint8_t* dataStart = (uint8_t*)data;
- uint8_t* dataPtr = (dataStart + *offset);
- //uint8_t* dataEnd = (dataPtr+size);
- tnet_dns_qtype_t qtype;
- tnet_dns_qclass_t qclass;
- uint32_t ttl;
- uint16_t rdlength;
- char* qname = tsk_null;
-
- /* Check validity */
- if (!dataPtr || !size){
- goto bail;
- }
-
- /* == Parse QNAME == */
- tnet_dns_rr_qname_deserialize(dataStart, &qname, offset);
- dataPtr = (dataStart + *offset);
- /* == Parse QTYPE == */
- qtype = (tnet_dns_qtype_t)tnet_ntohs_2(dataPtr);
- dataPtr += 2, *offset += 2;
- /* == Parse QCLASS == */
- qclass = (tnet_dns_qclass_t)tnet_ntohs_2(dataPtr);
- dataPtr += 2, *offset += 2;
- /* == Parse TTL == */
- ttl = (uint32_t)tnet_htonl_2(dataPtr);
- dataPtr += 4, *offset += 4;
- /* == Parse RDLENGTH == */
- rdlength = tnet_ntohs_2(dataPtr);
- dataPtr += 2, *offset += 2;
-
- switch (qtype){
- case qtype_a:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_a_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_aaaa:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_aaaa_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_cname:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_cname_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_mx:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_mx_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_naptr:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_naptr_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_ns:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_ns_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_opt:
- {
- unsigned payload_size = qclass;
- rr = (tnet_dns_rr_t *)tnet_dns_opt_create(payload_size);
- break;
- }
-
- case qtype_ptr:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_ptr_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_soa:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_soa_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_srv:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_srv_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- case qtype_txt:
- {
- rr = (tnet_dns_rr_t *)tnet_dns_txt_create(qname, qclass, ttl, rdlength, dataStart, *offset);
- break;
- }
-
- default:
- {
- TSK_DEBUG_ERROR("NOT IMPLEMENTED");
- break;
- }
- }
+ tnet_dns_rr_t *rr = tsk_null;
+ uint8_t* dataStart = (uint8_t*)data;
+ uint8_t* dataPtr = (dataStart + *offset);
+ //uint8_t* dataEnd = (dataPtr+size);
+ tnet_dns_qtype_t qtype;
+ tnet_dns_qclass_t qclass;
+ uint32_t ttl;
+ uint16_t rdlength;
+ char* qname = tsk_null;
+
+ /* Check validity */
+ if (!dataPtr || !size) {
+ goto bail;
+ }
+
+ /* == Parse QNAME == */
+ tnet_dns_rr_qname_deserialize(dataStart, &qname, offset);
+ dataPtr = (dataStart + *offset);
+ /* == Parse QTYPE == */
+ qtype = (tnet_dns_qtype_t)tnet_ntohs_2(dataPtr);
+ dataPtr += 2, *offset += 2;
+ /* == Parse QCLASS == */
+ qclass = (tnet_dns_qclass_t)tnet_ntohs_2(dataPtr);
+ dataPtr += 2, *offset += 2;
+ /* == Parse TTL == */
+ ttl = (uint32_t)tnet_htonl_2(dataPtr);
+ dataPtr += 4, *offset += 4;
+ /* == Parse RDLENGTH == */
+ rdlength = tnet_ntohs_2(dataPtr);
+ dataPtr += 2, *offset += 2;
+
+ switch (qtype) {
+ case qtype_a: {
+ rr = (tnet_dns_rr_t *)tnet_dns_a_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_aaaa: {
+ rr = (tnet_dns_rr_t *)tnet_dns_aaaa_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_cname: {
+ rr = (tnet_dns_rr_t *)tnet_dns_cname_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_mx: {
+ rr = (tnet_dns_rr_t *)tnet_dns_mx_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_naptr: {
+ rr = (tnet_dns_rr_t *)tnet_dns_naptr_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_ns: {
+ rr = (tnet_dns_rr_t *)tnet_dns_ns_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_opt: {
+ unsigned payload_size = qclass;
+ rr = (tnet_dns_rr_t *)tnet_dns_opt_create(payload_size);
+ break;
+ }
+
+ case qtype_ptr: {
+ rr = (tnet_dns_rr_t *)tnet_dns_ptr_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_soa: {
+ rr = (tnet_dns_rr_t *)tnet_dns_soa_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_srv: {
+ rr = (tnet_dns_rr_t *)tnet_dns_srv_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ case qtype_txt: {
+ rr = (tnet_dns_rr_t *)tnet_dns_txt_create(qname, qclass, ttl, rdlength, dataStart, *offset);
+ break;
+ }
+
+ default: {
+ TSK_DEBUG_ERROR("NOT IMPLEMENTED");
+ break;
+ }
+ }
bail:
- TSK_FREE(qname);
+ TSK_FREE(qname);
- *offset += rdlength;
- return rr;
+ *offset += rdlength;
+ return rr;
}
/** Serializes a DNS RR.
*/
int tnet_dns_rr_serialize(const tnet_dns_rr_t* rr, tsk_buffer_t *output)
{
- if (!rr || !output){
- return -1;
- }
-
- /*=== NAME ===*/
- {
- tnet_dns_rr_qname_serialize(rr->name, output);
- }
-
- /*=== TYPE ===*/
- {
- uint16_t qtype = tnet_htons(rr->qtype);
- tsk_buffer_append(output, &(qtype), 2);
- }
-
- /*=== CLASS ===*/
- {
- uint16_t qclass = tnet_htons(rr->qclass);
- tsk_buffer_append(output, &(qclass), 2);
- }
-
- /*=== TTL ===*/
- {
- uint32_t ttl = (uint32_t)tnet_htonl(rr->ttl);
- tsk_buffer_append(output, &(ttl), 4);
- }
-
- /*=== RDLENGTH ===*/
- {
- uint16_t length = tnet_htons(rr->rdlength);
- tsk_buffer_append(output, &(length), 2);
- }
-
- /*=== RDATA : Request never contains data
- ===*/
- if (!rr->rpdata){
- goto done;
- }
-
- switch (rr->qtype){
- case qtype_a:
- case qtype_aaaa:
- case qtype_cname:
- case qtype_mx:
- case qtype_naptr:
- case qtype_ns:
- case qtype_opt:
- case qtype_ptr:
- case qtype_soa:
- case qtype_srv:
- case qtype_txt:
- default:
- {
- TSK_DEBUG_WARN("DNS Request should not contains RDATA (not supported).");
- break;
- }
- }
+ if (!rr || !output) {
+ return -1;
+ }
+
+ /*=== NAME ===*/
+ {
+ tnet_dns_rr_qname_serialize(rr->name, output);
+ }
+
+ /*=== TYPE ===*/
+ {
+ uint16_t qtype = tnet_htons(rr->qtype);
+ tsk_buffer_append(output, &(qtype), 2);
+ }
+
+ /*=== CLASS ===*/
+ {
+ uint16_t qclass = tnet_htons(rr->qclass);
+ tsk_buffer_append(output, &(qclass), 2);
+ }
+
+ /*=== TTL ===*/
+ {
+ uint32_t ttl = (uint32_t)tnet_htonl(rr->ttl);
+ tsk_buffer_append(output, &(ttl), 4);
+ }
+
+ /*=== RDLENGTH ===*/
+ {
+ uint16_t length = tnet_htons(rr->rdlength);
+ tsk_buffer_append(output, &(length), 2);
+ }
+
+ /*=== RDATA : Request never contains data
+ ===*/
+ if (!rr->rpdata) {
+ goto done;
+ }
+
+ switch (rr->qtype) {
+ case qtype_a:
+ case qtype_aaaa:
+ case qtype_cname:
+ case qtype_mx:
+ case qtype_naptr:
+ case qtype_ns:
+ case qtype_opt:
+ case qtype_ptr:
+ case qtype_soa:
+ case qtype_srv:
+ case qtype_txt:
+ default: {
+ TSK_DEBUG_WARN("DNS Request should not contains RDATA (not supported).");
+ break;
+ }
+ }
done:
- return 0;
+ return 0;
}
@@ -422,27 +409,26 @@ done:
//
static tsk_object_t* tnet_dns_rr_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_rr_t *rr = self;
- if (rr){
- tnet_dns_rr_init(rr, qtype_any, qclass_any);
- }
- return self;
+ tnet_dns_rr_t *rr = self;
+ if (rr) {
+ tnet_dns_rr_init(rr, qtype_any, qclass_any);
+ }
+ return self;
}
static tsk_object_t* tnet_dns_rr_dtor(tsk_object_t * self)
{
- tnet_dns_rr_t *rr = self;
- if (rr){
- tnet_dns_rr_deinit(rr);
- }
- return self;
+ tnet_dns_rr_t *rr = self;
+ if (rr) {
+ tnet_dns_rr_deinit(rr);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_rr_def_s =
-{
- sizeof(tnet_dns_rr_t),
- tnet_dns_rr_ctor,
- tnet_dns_rr_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_rr_def_s = {
+ sizeof(tnet_dns_rr_t),
+ tnet_dns_rr_ctor,
+ tnet_dns_rr_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_rr_def_t = &tnet_dns_rr_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_rr.h b/tinyNET/src/dns/tnet_dns_rr.h
index f4a1b6b..895c648 100755
--- a/tinyNET/src/dns/tnet_dns_rr.h
+++ b/tinyNET/src/dns/tnet_dns_rr.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -46,106 +46,103 @@ TNET_BEGIN_DECLS
/** RFC 1035 - 3.2.2. TYPE values
* @sa http://en.wikipedia.org/wiki/List_of_DNS_record_types
*/
-typedef enum tnet_dns_qtype_e
-{
- qtype_a = 1, /**< A 1 a host address */
- qtype_ns = 2, /**< NS 2 an authoritative name server */
- qtype_md = 3, /**< MD 3 a mail destination (Obsolete - use MX) */
- qtype_mf = 4, /**< MF 4 a mail forwarder (Obsolete - use MX) */
- qtype_cname = 5, /**< CNAME 5 the canonical name for an alias */
- qtype_soa = 6, /**< SOA 6 marks the start of a zone of authority */
- qtype_mb = 7, /**< MB 7 a mailbox domain name (EXPERIMENTAL) */
- qtype_mg = 8, /**< MG 8 a mail group member (EXPERIMENTAL) */
- qtype_mr = 9, /**< MR 9 a mail rename domain name (EXPERIMENTAL) */
- qtype_null = 10, /**< NULL 10 a null RR (EXPERIMENTAL) */
- qtype_wks = 11, /**< WKS 11 a well known service description */
- qtype_ptr = 12, /**< PTR 12 a domain name pointer */
- qtype_hinfo = 13, /**< HINFO 13 host information */
- qtype_minfo = 14, /**< MINFO 14 mailbox or mail list information */
- qtype_mx = 15, /**< MX 15 mail exchange */
- qtype_txt = 16, /**< TXT 16 text strings */
-
- qtype_aaaa = 28, /**< AAAA 28 IPv6 host address */
-
- qtype_srv = 33, /**< SRV 33 Service locator */
-
- qtype_naptr = 35, /**< NAPTR 35 Naming Authority Pointer */
-
- qtype_opt = 41, /**< OPT 41 Option */
-
- qtype_ipseckey = 45,/**< IPSECKEY 45 IPSEC Key */
-
- qtype_spf = 99, /**< SPF 99 SPF record */
-
- qtype_any = 255 /**< * 255 A request for all records (3.2.3. QTYPE values)*/
+typedef enum tnet_dns_qtype_e {
+ qtype_a = 1, /**< A 1 a host address */
+ qtype_ns = 2, /**< NS 2 an authoritative name server */
+ qtype_md = 3, /**< MD 3 a mail destination (Obsolete - use MX) */
+ qtype_mf = 4, /**< MF 4 a mail forwarder (Obsolete - use MX) */
+ qtype_cname = 5, /**< CNAME 5 the canonical name for an alias */
+ qtype_soa = 6, /**< SOA 6 marks the start of a zone of authority */
+ qtype_mb = 7, /**< MB 7 a mailbox domain name (EXPERIMENTAL) */
+ qtype_mg = 8, /**< MG 8 a mail group member (EXPERIMENTAL) */
+ qtype_mr = 9, /**< MR 9 a mail rename domain name (EXPERIMENTAL) */
+ qtype_null = 10, /**< NULL 10 a null RR (EXPERIMENTAL) */
+ qtype_wks = 11, /**< WKS 11 a well known service description */
+ qtype_ptr = 12, /**< PTR 12 a domain name pointer */
+ qtype_hinfo = 13, /**< HINFO 13 host information */
+ qtype_minfo = 14, /**< MINFO 14 mailbox or mail list information */
+ qtype_mx = 15, /**< MX 15 mail exchange */
+ qtype_txt = 16, /**< TXT 16 text strings */
+
+ qtype_aaaa = 28, /**< AAAA 28 IPv6 host address */
+
+ qtype_srv = 33, /**< SRV 33 Service locator */
+
+ qtype_naptr = 35, /**< NAPTR 35 Naming Authority Pointer */
+
+ qtype_opt = 41, /**< OPT 41 Option */
+
+ qtype_ipseckey = 45,/**< IPSECKEY 45 IPSEC Key */
+
+ qtype_spf = 99, /**< SPF 99 SPF record */
+
+ qtype_any = 255 /**< * 255 A request for all records (3.2.3. QTYPE values)*/
}
tnet_dns_qtype_t;
/** RFC 1035 - 3.2.4. CLASS values
*/
-typedef enum tnet_dns_qclass_e
-{
- qclass_in = 1, /**< IN 1 the Internet */
- qclass_ics = 2, /**< CS 2 the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
- qclass_ch = 3, /**< CH 3 the CHAOS class */
- qclass_hs = 4, /**< HS 4 Hesiod [Dyer 87] */
-
- qclass_any = 255 /**< * 255 any class (3.2.5. QCLASS values) */
+typedef enum tnet_dns_qclass_e {
+ qclass_in = 1, /**< IN 1 the Internet */
+ qclass_ics = 2, /**< CS 2 the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
+ qclass_ch = 3, /**< CH 3 the CHAOS class */
+ qclass_hs = 4, /**< HS 4 Hesiod [Dyer 87] */
+
+ qclass_any = 255 /**< * 255 any class (3.2.5. QCLASS values) */
}
tnet_dns_qclass_t;
-/** RFC 1034 (3.6. Resource Records) and 1035 (3.2.1. Format)
+/** RFC 1034 (3.6. Resource Records) and 1035 (3.2.1. Format)
*/
-typedef struct tnet_dns_rr_s
-{
- TSK_DECLARE_OBJECT;
-
- /* RFC 1035 - 3.2.1. Format
- 1 1 1 1 1 1
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- | |
- / /
- / NAME /
- | |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- | TYPE |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- | CLASS |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- | TTL |
- | |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- | RDLENGTH |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
- / RDATA /
- / /
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
-
- tsk_bool_t initialized;
-
- /** An owner name, i.e., the name of the node to which this resource record pertains. */
- char* name;
-
- /** Two octets containing one of the RR TYPE codes. */
- tnet_dns_qtype_t qtype;
-
- /** Two octets containing one of the RR CLASS codes. */
- tnet_dns_qclass_t qclass;
-
- /** A 32 bit signed integer that specifies the time interval (seconds) that the resource record may be cached before the source
- of the information should again be consulted.
- Zero values are interpreted to mean that the RR can only be used for the transaction in progress, and should not be cached.
- For example, SOA records are always distributed with a zero TTL to prohibit caching. Zero values can also be used for extremely volatile data. */
- int32_t ttl;
-
- /** An unsigned 16 bit integer that specifies the length in octets of the RDATA field. */
- uint16_t rdlength;
-
- /** A variable length string of octets that describes the resource.
- The format of this information varies according to the TYPE and CLASS of the resource record.*/
- void *rpdata;
+typedef struct tnet_dns_rr_s {
+ TSK_DECLARE_OBJECT;
+
+ /* RFC 1035 - 3.2.1. Format
+ 1 1 1 1 1 1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | |
+ / /
+ / NAME /
+ | |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | TYPE |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | CLASS |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | TTL |
+ | |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ | RDLENGTH |
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
+ / RDATA /
+ / /
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ */
+
+ tsk_bool_t initialized;
+
+ /** An owner name, i.e., the name of the node to which this resource record pertains. */
+ char* name;
+
+ /** Two octets containing one of the RR TYPE codes. */
+ tnet_dns_qtype_t qtype;
+
+ /** Two octets containing one of the RR CLASS codes. */
+ tnet_dns_qclass_t qclass;
+
+ /** A 32 bit signed integer that specifies the time interval (seconds) that the resource record may be cached before the source
+ of the information should again be consulted.
+ Zero values are interpreted to mean that the RR can only be used for the transaction in progress, and should not be cached.
+ For example, SOA records are always distributed with a zero TTL to prohibit caching. Zero values can also be used for extremely volatile data. */
+ int32_t ttl;
+
+ /** An unsigned 16 bit integer that specifies the length in octets of the RDATA field. */
+ uint16_t rdlength;
+
+ /** A variable length string of octets that describes the resource.
+ The format of this information varies according to the TYPE and CLASS of the resource record.*/
+ void *rpdata;
}
tnet_dns_rr_t;
diff --git a/tinyNET/src/dns/tnet_dns_soa.c b/tinyNET/src/dns/tnet_dns_soa.c
index a1844f4..8aefc5f 100755
--- a/tinyNET/src/dns/tnet_dns_soa.c
+++ b/tinyNET/src/dns/tnet_dns_soa.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -36,7 +36,7 @@
tnet_dns_soa_t* tnet_dns_soa_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_soa_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_soa_def_t, name, qclass, ttl, rdlength, data, offset);
}
//=================================================================================================
@@ -44,65 +44,64 @@ tnet_dns_soa_t* tnet_dns_soa_create(const char* name, tnet_dns_qclass_t qclass,
//
static tsk_object_t* tnet_dns_soa_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_soa_t *soa = self;
- if(soa){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_soa_t *soa = self;
+ if(soa) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(soa), qtype_soa, qclass);
- TNET_DNS_RR(soa)->name = tsk_strdup(name);
- TNET_DNS_RR(soa)->rdlength = rdlength;
- TNET_DNS_RR(soa)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(soa), qtype_soa, qclass);
+ TNET_DNS_RR(soa)->name = tsk_strdup(name);
+ TNET_DNS_RR(soa)->rdlength = rdlength;
+ TNET_DNS_RR(soa)->ttl = ttl;
- if(rdlength)
- { // ==> DESERIALIZATION
- /* MNAME */
- tnet_dns_rr_qname_deserialize(data, &(soa->mname), &offset);
- /* RNAME */
- tnet_dns_rr_qname_deserialize(data, &(soa->rname), &offset);
- /* SERIAL */
- soa->serial = tnet_htonl_2(((uint8_t*)data) + offset),
- offset += 2;
- /* REFRESH */
- soa->refresh = tnet_htonl_2(((uint8_t*)data) + offset),
- offset += 2;
- /* RETRY */
- soa->retry = tnet_htonl_2(((uint8_t*)data) + offset),
- offset += 2;
- /* EXPIRE */
- soa->expire = tnet_htonl_2(((uint8_t*)data) + offset),
- offset += 2;
- /* MINIMUM */
- soa->minimum = tnet_htonl_2(((uint8_t*)data) + offset),
- offset += 2;
- }
- }
- return self;
+ if(rdlength) {
+ // ==> DESERIALIZATION
+ /* MNAME */
+ tnet_dns_rr_qname_deserialize(data, &(soa->mname), &offset);
+ /* RNAME */
+ tnet_dns_rr_qname_deserialize(data, &(soa->rname), &offset);
+ /* SERIAL */
+ soa->serial = tnet_htonl_2(((uint8_t*)data) + offset),
+ offset += 2;
+ /* REFRESH */
+ soa->refresh = tnet_htonl_2(((uint8_t*)data) + offset),
+ offset += 2;
+ /* RETRY */
+ soa->retry = tnet_htonl_2(((uint8_t*)data) + offset),
+ offset += 2;
+ /* EXPIRE */
+ soa->expire = tnet_htonl_2(((uint8_t*)data) + offset),
+ offset += 2;
+ /* MINIMUM */
+ soa->minimum = tnet_htonl_2(((uint8_t*)data) + offset),
+ offset += 2;
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_soa_dtor(tsk_object_t * self)
-{
- tnet_dns_soa_t *soa = self;
- if(soa){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(soa));
+static tsk_object_t* tnet_dns_soa_dtor(tsk_object_t * self)
+{
+ tnet_dns_soa_t *soa = self;
+ if(soa) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(soa));
- TSK_FREE(soa->mname);
- TSK_FREE(soa->rname);
- }
- return self;
+ TSK_FREE(soa->mname);
+ TSK_FREE(soa->rname);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_soa_def_s =
-{
- sizeof(tnet_dns_soa_t),
- tnet_dns_soa_ctor,
- tnet_dns_soa_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_soa_def_s = {
+ sizeof(tnet_dns_soa_t),
+ tnet_dns_soa_ctor,
+ tnet_dns_soa_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_soa_def_t = &tnet_dns_soa_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_soa.h b/tinyNET/src/dns/tnet_dns_soa.h
index 298e907..9faea75 100755
--- a/tinyNET/src/dns/tnet_dns_soa.h
+++ b/tinyNET/src/dns/tnet_dns_soa.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -35,12 +35,11 @@
TNET_BEGIN_DECLS
-typedef struct tnet_dns_soa_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_soa_s {
+ TNET_DECLARE_DNS_RR;
- /* RFC 1035 - 3.3.13. SOA RDATA format
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ /* RFC 1035 - 3.3.13. SOA RDATA format
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/ MNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
@@ -61,14 +60,14 @@ typedef struct tnet_dns_soa_s
| MINIMUM |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- char* mname;
- char* rname;
- uint32_t serial;
- uint32_t refresh;
- uint32_t retry;
- uint32_t expire;
- uint32_t minimum;
+ */
+ char* mname;
+ char* rname;
+ uint32_t serial;
+ uint32_t refresh;
+ uint32_t retry;
+ uint32_t expire;
+ uint32_t minimum;
}
tnet_dns_soa_t;
diff --git a/tinyNET/src/dns/tnet_dns_srv.c b/tinyNET/src/dns/tnet_dns_srv.c
index 4625d68..852bda0 100755
--- a/tinyNET/src/dns/tnet_dns_srv.c
+++ b/tinyNET/src/dns/tnet_dns_srv.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,7 +38,7 @@
*/
tnet_dns_srv_t* tnet_dns_srv_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_srv_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_srv_def_t, name, qclass, ttl, rdlength, data, offset);
}
//=================================================================================================
@@ -46,88 +46,87 @@ tnet_dns_srv_t* tnet_dns_srv_create(const char* name, tnet_dns_qclass_t qclass,
//
static tsk_object_t* tnet_dns_srv_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_srv_t *srv = self;
- if(srv){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_srv_t *srv = self;
+ if(srv) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(srv), qtype_srv, qclass);
- TNET_DNS_RR(srv)->name = tsk_strdup(name);
- TNET_DNS_RR(srv)->rdlength = rdlength;
- TNET_DNS_RR(srv)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(srv), qtype_srv, qclass);
+ TNET_DNS_RR(srv)->name = tsk_strdup(name);
+ TNET_DNS_RR(srv)->rdlength = rdlength;
+ TNET_DNS_RR(srv)->ttl = ttl;
- if(rdlength){
- // ==> DESERIALIZATION
- /* Priority */
- srv->priority = tnet_ntohs_2(((uint8_t*)data) + offset),
- offset += 2;
- /* Weight */
- srv->weight = tnet_ntohs_2(((uint8_t*)data) + offset),
- offset += 2;
- /* Port */
- srv->port = tnet_ntohs_2(((uint8_t*)data) + offset),
- offset += 2;
- /* Target */
- tnet_dns_rr_qname_deserialize(data, &(srv->target), &offset);
- }
- }
- return self;
+ if(rdlength) {
+ // ==> DESERIALIZATION
+ /* Priority */
+ srv->priority = tnet_ntohs_2(((uint8_t*)data) + offset),
+ offset += 2;
+ /* Weight */
+ srv->weight = tnet_ntohs_2(((uint8_t*)data) + offset),
+ offset += 2;
+ /* Port */
+ srv->port = tnet_ntohs_2(((uint8_t*)data) + offset),
+ offset += 2;
+ /* Target */
+ tnet_dns_rr_qname_deserialize(data, &(srv->target), &offset);
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_srv_dtor(tsk_object_t * self)
-{
- tnet_dns_srv_t *srv = self;
- if(srv){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(srv));
+static tsk_object_t* tnet_dns_srv_dtor(tsk_object_t * self)
+{
+ tnet_dns_srv_t *srv = self;
+ if(srv) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(srv));
- TSK_FREE(srv->target);
- }
- return self;
+ TSK_FREE(srv->target);
+ }
+ return self;
}
static int tnet_dns_srv_cmp(const tsk_object_t *obj1, const tsk_object_t *obj2)
-{
- const tnet_dns_rr_t* rr1 = obj1;
- const tnet_dns_rr_t* rr2 = obj2;
+{
+ const tnet_dns_rr_t* rr1 = obj1;
+ const tnet_dns_rr_t* rr2 = obj2;
+
+ if(rr1 && rr2 && (rr1->qtype==qtype_srv) && (rr2->qtype==qtype_srv)) {
+ const tnet_dns_srv_t* srv1 = (tnet_dns_srv_t*)rr1;
+ const tnet_dns_srv_t* srv2 = (tnet_dns_srv_t*)rr2;
- if(rr1 && rr2 && (rr1->qtype==qtype_srv) && (rr2->qtype==qtype_srv)){
- const tnet_dns_srv_t* srv1 = (tnet_dns_srv_t*)rr1;
- const tnet_dns_srv_t* srv2 = (tnet_dns_srv_t*)rr2;
+ /* Compare priorities. */
+ if(srv1->priority < srv2->priority) { /* Lowest priority is tried first. */
+ return 1;
+ }
+ else if(srv1->priority > srv2->priority) {
+ return -1;
+ }
- /* Compare priorities. */
- if(srv1->priority < srv2->priority){ /* Lowest priority is tried first. */
- return 1;
- }
- else if(srv1->priority > srv2->priority){
- return -1;
- }
+ /* Compare weight */
+ if(srv1->weight > srv2->weight) {
+ return 1;
+ }
+ else if(srv1->weight < srv2->weight) {
+ return -1;
+ }
- /* Compare weight */
- if(srv1->weight > srv2->weight){
- return 1;
- }
- else if(srv1->weight < srv2->weight){
- return -1;
- }
-
- return 0;
- }
- else{
- return -1;
- }
+ return 0;
+ }
+ else {
+ return -1;
+ }
}
-static const tsk_object_def_t tnet_dns_srv_def_s =
-{
- sizeof(tnet_dns_srv_t),
- tnet_dns_srv_ctor,
- tnet_dns_srv_dtor,
- tnet_dns_srv_cmp,
+static const tsk_object_def_t tnet_dns_srv_def_s = {
+ sizeof(tnet_dns_srv_t),
+ tnet_dns_srv_ctor,
+ tnet_dns_srv_dtor,
+ tnet_dns_srv_cmp,
};
const tsk_object_def_t *tnet_dns_srv_def_t = &tnet_dns_srv_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_srv.h b/tinyNET/src/dns/tnet_dns_srv.h
index c8cc94d..7a3dc83 100755
--- a/tinyNET/src/dns/tnet_dns_srv.h
+++ b/tinyNET/src/dns/tnet_dns_srv.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,14 +38,13 @@ TNET_BEGIN_DECLS
/** DNS SRV Resource Record
*/
-typedef struct tnet_dns_srv_s
-{
- TNET_DECLARE_DNS_RR;
-
- uint16_t priority;
- uint16_t weight;
- uint16_t port;
- char* target;
+typedef struct tnet_dns_srv_s {
+ TNET_DECLARE_DNS_RR;
+
+ uint16_t priority;
+ uint16_t weight;
+ uint16_t port;
+ char* target;
}
tnet_dns_srv_t;
diff --git a/tinyNET/src/dns/tnet_dns_txt.c b/tinyNET/src/dns/tnet_dns_txt.c
index 9d152e9..3a76d9b 100755
--- a/tinyNET/src/dns/tnet_dns_txt.c
+++ b/tinyNET/src/dns/tnet_dns_txt.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,7 +38,7 @@
tnet_dns_txt_t* tnet_dns_txt_create(const char* name, tnet_dns_qclass_t qclass, uint32_t ttl, uint16_t rdlength, const void* data, tsk_size_t offset)
{
- return tsk_object_new(tnet_dns_txt_def_t, name, qclass, ttl, rdlength, data, offset);
+ return tsk_object_new(tnet_dns_txt_def_t, name, qclass, ttl, rdlength, data, offset);
}
//=================================================================================================
@@ -46,47 +46,46 @@ tnet_dns_txt_t* tnet_dns_txt_create(const char* name, tnet_dns_qclass_t qclass,
//
static tsk_object_t* tnet_dns_txt_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dns_txt_t *txt = self;
- if(txt){
- const char* name = va_arg(*app, const char*);
- tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
- uint32_t ttl = va_arg(*app, uint32_t);
- uint16_t rdlength = tsk_va_arg_u16(*app);
- const void* data = va_arg(*app, const void*);
- tsk_size_t offset = va_arg(*app, tsk_size_t);
+ tnet_dns_txt_t *txt = self;
+ if(txt) {
+ const char* name = va_arg(*app, const char*);
+ tnet_dns_qclass_t qclass = va_arg(*app, tnet_dns_qclass_t);
+ uint32_t ttl = va_arg(*app, uint32_t);
+ uint16_t rdlength = tsk_va_arg_u16(*app);
+ const void* data = va_arg(*app, const void*);
+ tsk_size_t offset = va_arg(*app, tsk_size_t);
- /* init base */
- tnet_dns_rr_init(TNET_DNS_RR(txt), qtype_txt, qclass);
- TNET_DNS_RR(txt)->name = tsk_strdup(name);
- TNET_DNS_RR(txt)->rdlength = rdlength;
- TNET_DNS_RR(txt)->ttl = ttl;
+ /* init base */
+ tnet_dns_rr_init(TNET_DNS_RR(txt), qtype_txt, qclass);
+ TNET_DNS_RR(txt)->name = tsk_strdup(name);
+ TNET_DNS_RR(txt)->rdlength = rdlength;
+ TNET_DNS_RR(txt)->ttl = ttl;
- if(rdlength){
- // ==> DESERIALIZATION
- /* TXT-DATA */
- tnet_dns_rr_charstring_deserialize(data, &(txt->txt_data), &offset);
- }
- }
- return self;
+ if(rdlength) {
+ // ==> DESERIALIZATION
+ /* TXT-DATA */
+ tnet_dns_rr_charstring_deserialize(data, &(txt->txt_data), &offset);
+ }
+ }
+ return self;
}
-static tsk_object_t* tnet_dns_txt_dtor(tsk_object_t * self)
-{
- tnet_dns_txt_t *txt = self;
- if(txt){
- /* deinit base */
- tnet_dns_rr_deinit(TNET_DNS_RR(txt));
+static tsk_object_t* tnet_dns_txt_dtor(tsk_object_t * self)
+{
+ tnet_dns_txt_t *txt = self;
+ if(txt) {
+ /* deinit base */
+ tnet_dns_rr_deinit(TNET_DNS_RR(txt));
- TSK_FREE(txt->txt_data);
- }
- return self;
+ TSK_FREE(txt->txt_data);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dns_txt_def_s =
-{
- sizeof(tnet_dns_txt_t),
- tnet_dns_txt_ctor,
- tnet_dns_txt_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dns_txt_def_s = {
+ sizeof(tnet_dns_txt_t),
+ tnet_dns_txt_ctor,
+ tnet_dns_txt_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dns_txt_def_t = &tnet_dns_txt_def_s;
diff --git a/tinyNET/src/dns/tnet_dns_txt.h b/tinyNET/src/dns/tnet_dns_txt.h
index 05f54d9..0bac6c7 100755
--- a/tinyNET/src/dns/tnet_dns_txt.h
+++ b/tinyNET/src/dns/tnet_dns_txt.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,16 +38,15 @@ TNET_BEGIN_DECLS
/** DNS TXT Resource Record
*/
-typedef struct tnet_dns_txt_s
-{
- TNET_DECLARE_DNS_RR;
+typedef struct tnet_dns_txt_s {
+ TNET_DECLARE_DNS_RR;
- /* RFC 1035 - 3.3.14. TXT RDATA format
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ /* RFC 1035 - 3.3.14. TXT RDATA format
+ +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
/ TXT-DATA /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- */
- char* txt_data;
+ */
+ char* txt_data;
}
tnet_dns_txt_t;
diff --git a/tinyNET/src/ice/tnet_ice.c b/tinyNET/src/ice/tnet_ice.c
index 196009b..1252ff6 100755
--- a/tinyNET/src/ice/tnet_ice.c
+++ b/tinyNET/src/ice/tnet_ice.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2010-2015 Mamadou DIOP
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/ice/tnet_ice.h b/tinyNET/src/ice/tnet_ice.h
index daffd08..53f9d22 100755
--- a/tinyNET/src/ice/tnet_ice.h
+++ b/tinyNET/src/ice/tnet_ice.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2010-2015 Mamadou DIOP
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/ice/tnet_ice_candidate.c b/tinyNET/src/ice/tnet_ice_candidate.c
index bb75b33..7900933 100755
--- a/tinyNET/src/ice/tnet_ice_candidate.c
+++ b/tinyNET/src/ice/tnet_ice_candidate.c
@@ -34,15 +34,15 @@
#include <ctype.h>
static int _tnet_ice_candidate_tostring(
- uint8_t* foundation,
- uint32_t comp_id,
- const char* transport_str,
- uint32_t priority,
- const char* connection_addr,
- tnet_port_t port,
- const char* cand_type_str,
- const tsk_params_L_t *extension_att_list,
- char** output);
+ uint8_t* foundation,
+ uint32_t comp_id,
+ const char* transport_str,
+ uint32_t priority,
+ const char* connection_addr,
+ tnet_port_t port,
+ const char* cand_type_str,
+ const tsk_params_L_t *extension_att_list,
+ char** output);
static const char* _tnet_ice_candidate_get_foundation(tnet_ice_cand_type_t type);
static tnet_stun_pkt_t * _tnet_ice_candidate_stun_create_bind_request(tnet_ice_candidate_t* self, const char* username, const char* password);
static tsk_bool_t _tnet_ice_candidate_stun_transac_id_equals(const tnet_stun_transac_id_t id1, const tnet_stun_transac_id_t id2);
@@ -54,7 +54,7 @@ static tnet_ice_cand_type_t _tnet_ice_candtype_get_transport_type(const char* ca
static tsk_object_t* tnet_ice_candidate_ctor(tsk_object_t * self, va_list * app)
{
tnet_ice_candidate_t *candidate = self;
- if (candidate){
+ if (candidate) {
candidate->extension_att_list = tsk_list_create();
}
return self;
@@ -63,23 +63,23 @@ static tsk_object_t* tnet_ice_candidate_ctor(tsk_object_t * self, va_list * app)
static tsk_object_t* tnet_ice_candidate_dtor(tsk_object_t * self)
{
tnet_ice_candidate_t *candidate = self;
- if (candidate){
+ if (candidate) {
TSK_SAFE_FREE(candidate->transport_str);
TSK_SAFE_FREE(candidate->cand_type_str);
TSK_OBJECT_SAFE_FREE(candidate->extension_att_list);
TSK_OBJECT_SAFE_FREE(candidate->socket);
-
-
+
+
TSK_SAFE_FREE(candidate->stun.nonce);
TSK_SAFE_FREE(candidate->stun.realm);
TSK_SAFE_FREE(candidate->stun.srflx_addr);
-
+
TSK_SAFE_FREE(candidate->turn.relay_addr);
TSK_OBJECT_SAFE_FREE(candidate->turn.ss);
-
+
TSK_SAFE_FREE(candidate->ufrag);
TSK_SAFE_FREE(candidate->pwd);
-
+
TSK_SAFE_FREE(candidate->tostring);
}
return self;
@@ -89,16 +89,19 @@ static int tnet_ice_candidate_cmp(const tsk_object_t *_s1, const tsk_object_t *_
{
const tnet_ice_candidate_t *c1 = _s1;
const tnet_ice_candidate_t *c2 = _s2;
-
- if (c1 && c2){
+
+ if (c1 && c2) {
return (int)(c1->priority - c2->priority);
}
- else if (!c1 && !c2) return 0;
- else return -1;
+ else if (!c1 && !c2) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
}
-static const tsk_object_def_t tnet_ice_candidate_def_s =
-{
+static const tsk_object_def_t tnet_ice_candidate_def_s = {
sizeof(tnet_ice_candidate_t),
tnet_ice_candidate_ctor,
tnet_ice_candidate_dtor,
@@ -108,12 +111,12 @@ static const tsk_object_def_t tnet_ice_candidate_def_s =
tnet_ice_candidate_t* tnet_ice_candidate_create(tnet_ice_cand_type_t type_e, tnet_socket_t* socket, tsk_bool_t is_ice_jingle, tsk_bool_t is_rtp, tsk_bool_t is_video, const char* ufrag, const char* pwd, const char *foundation)
{
tnet_ice_candidate_t* candidate;
-
- if (!(candidate = tsk_object_new(&tnet_ice_candidate_def_s))){
+
+ if (!(candidate = tsk_object_new(&tnet_ice_candidate_def_s))) {
TSK_DEBUG_ERROR("Failed to create candidate");
return tsk_null;
}
-
+
candidate->type_e = type_e;
candidate->socket = tsk_object_ref(socket);
candidate->local_pref = 0xFFFF;
@@ -121,20 +124,20 @@ tnet_ice_candidate_t* tnet_ice_candidate_create(tnet_ice_cand_type_t type_e, tne
candidate->is_rtp = is_rtp;
candidate->is_video = is_video;
candidate->comp_id = is_rtp ? TNET_ICE_CANDIDATE_COMPID_RTP : TNET_ICE_CANDIDATE_COMPID_RTCP;
- if (foundation){
+ if (foundation) {
memcpy(candidate->foundation, foundation, TSK_MIN(tsk_strlen(foundation), TNET_ICE_CANDIDATE_FOUND_SIZE_PREF));
}
- else{
+ else {
tnet_ice_utils_compute_foundation((char*)candidate->foundation, TSK_MIN(sizeof(candidate->foundation), TNET_ICE_CANDIDATE_FOUND_SIZE_PREF));
}
candidate->priority = tnet_ice_utils_get_priority(candidate->type_e, candidate->local_pref, candidate->is_rtp);
- if (candidate->socket){
+ if (candidate->socket) {
memcpy(candidate->connection_addr, candidate->socket->ip, sizeof(candidate->socket->ip));
candidate->port = candidate->socket->port;
candidate->transport_e = socket->type;
}
tnet_ice_candidate_set_credential(candidate, ufrag, pwd);
-
+
return candidate;
}
@@ -144,104 +147,96 @@ tnet_ice_candidate_t* tnet_ice_candidate_parse(const char* str)
char *v, *copy, *saveptr;
int32_t k;
tnet_ice_candidate_t* candidate;
-
- if (tsk_strnullORempty(str)){
+
+ if (tsk_strnullORempty(str)) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
- if (!(candidate = tsk_object_new(&tnet_ice_candidate_def_s))){
+
+ if (!(candidate = tsk_object_new(&tnet_ice_candidate_def_s))) {
TSK_DEBUG_ERROR("Failed to create candidate");
return tsk_null;
}
-
+
k = 0;
copy = tsk_strdup(str);
v = tsk_strtok_r(copy, " ", &saveptr);
-
- while (v){
- switch (k){
- case 0:
- {
- memcpy(candidate->foundation, v, TSK_MIN(tsk_strlen(v), sizeof(candidate->foundation)));
- break;
- }
- case 1:
- {
- candidate->comp_id = atoi(v);
- break;
- }
- case 2:
- {
- candidate->transport_str = tsk_strdup(v);
- break;
- }
- case 3:
- {
- candidate->priority = atoi(v);
- break;
- }
- case 4:
- {
- memcpy(candidate->connection_addr, v, TSK_MIN(tsk_strlen(v), sizeof(candidate->connection_addr)));
- break;
- }
- case 5:
- {
- tnet_family_t family;
- candidate->port = atoi(v);
- family = tnet_get_family(candidate->connection_addr, candidate->port);
- candidate->transport_e = _tnet_ice_candidate_get_transport_type((family == AF_INET6), candidate->transport_str);
- break;
- }
- case 6:
- {
- v = tsk_strtok_r(tsk_null, " ", &saveptr);
- tsk_strupdate(&candidate->cand_type_str, v);
- candidate->type_e = _tnet_ice_candtype_get_transport_type(v);
- break;
- }
- default:
- {
- const char* name = v;
- const char* value = (v = tsk_strtok_r(tsk_null, " ", &saveptr));
- tsk_param_t* param = tsk_param_create(name, value);
- if (param){
- tsk_list_push_back_data(candidate->extension_att_list, (void**)&param);
- }
- break;
+
+ while (v) {
+ switch (k) {
+ case 0: {
+ memcpy(candidate->foundation, v, TSK_MIN(tsk_strlen(v), sizeof(candidate->foundation)));
+ break;
+ }
+ case 1: {
+ candidate->comp_id = atoi(v);
+ break;
+ }
+ case 2: {
+ candidate->transport_str = tsk_strdup(v);
+ break;
+ }
+ case 3: {
+ candidate->priority = atoi(v);
+ break;
+ }
+ case 4: {
+ memcpy(candidate->connection_addr, v, TSK_MIN(tsk_strlen(v), sizeof(candidate->connection_addr)));
+ break;
+ }
+ case 5: {
+ tnet_family_t family;
+ candidate->port = atoi(v);
+ family = tnet_get_family(candidate->connection_addr, candidate->port);
+ candidate->transport_e = _tnet_ice_candidate_get_transport_type((family == AF_INET6), candidate->transport_str);
+ break;
+ }
+ case 6: {
+ v = tsk_strtok_r(tsk_null, " ", &saveptr);
+ tsk_strupdate(&candidate->cand_type_str, v);
+ candidate->type_e = _tnet_ice_candtype_get_transport_type(v);
+ break;
+ }
+ default: {
+ const char* name = v;
+ const char* value = (v = tsk_strtok_r(tsk_null, " ", &saveptr));
+ tsk_param_t* param = tsk_param_create(name, value);
+ if (param) {
+ tsk_list_push_back_data(candidate->extension_att_list, (void**)&param);
}
+ break;
+ }
}
-
+
++k;
v = tsk_strtok_r(tsk_null, " ", &saveptr);
}
-
- if (k < 6){
+
+ if (k < 6) {
TSK_DEBUG_ERROR("Failed to parse: %s", str);
TSK_OBJECT_SAFE_FREE(candidate);
}
TSK_FREE(copy);
-
+
return candidate;
}
int tnet_ice_candidate_set_credential(tnet_ice_candidate_t* self, const char* ufrag, const char* pwd)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
tsk_strupdate(&self->ufrag, ufrag);
tsk_strupdate(&self->pwd, pwd);
-
+
return 0;
}
int tnet_ice_candidate_set_rflx_addr(tnet_ice_candidate_t* self, const char* addr, tnet_port_t port)
{
- if (!self || !addr || !port){
+ if (!self || !addr || !port) {
TSK_DEBUG_ERROR("Invalid argument");
return -1;
}
@@ -253,7 +248,7 @@ int tnet_ice_candidate_set_rflx_addr(tnet_ice_candidate_t* self, const char* add
const char* tnet_ice_candidate_get_att_value(const tnet_ice_candidate_t* self, const char* att_name)
{
- if (!self || !att_name){
+ if (!self || !att_name) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
@@ -262,7 +257,7 @@ const char* tnet_ice_candidate_get_att_value(const tnet_ice_candidate_t* self, c
int tnet_ice_candidate_set_local_pref(tnet_ice_candidate_t* self, uint16_t local_pref)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -275,12 +270,12 @@ const char* tnet_ice_candidate_tostring(tnet_ice_candidate_t* self)
{
const char* _transport_str;
char __str[255]; // always allocated: bad idea :(
-
- if (!self){
+
+ if (!self) {
TSK_DEBUG_ERROR("Invalid argument");
return tsk_null;
}
-
+
if (self->type_e == tnet_ice_cand_type_relay && self->turn.ss) {
enum tnet_turn_transport_e e_req_transport = tnet_turn_transport_udp;
tnet_turn_session_get_req_transport(self->turn.ss, &e_req_transport);
@@ -288,47 +283,45 @@ const char* tnet_ice_candidate_tostring(tnet_ice_candidate_t* self)
}
else {
_transport_str = self->transport_str ? self->transport_str : _tnet_ice_candidate_get_transport_str(self->transport_e);
- if (self->is_ice_jingle){
+ if (self->is_ice_jingle) {
tsk_size_t i, s = tsk_strlen(_transport_str);
memset(__str, 0, sizeof(__str));
- for (i = 0; i < s && i < sizeof(__str) / sizeof(__str[0]); ++i){
+ for (i = 0; i < s && i < sizeof(__str) / sizeof(__str[0]); ++i) {
__str[i] = tolower(_transport_str[i]);
}
_transport_str = &__str[0];
}
}
-
+
_tnet_ice_candidate_tostring(
- self->foundation,
- self->comp_id,
- _transport_str,
- self->priority,
- (tsk_strnullORempty(self->connection_addr) && self->socket) ? self->socket->ip : self->connection_addr,
- (self->port <= 0 && self->socket) ? self->socket->port : self->port,
- self->cand_type_str ? self->cand_type_str : _tnet_ice_candidate_get_candtype_str(self->type_e),
- self->extension_att_list,
- &self->tostring);
-
+ self->foundation,
+ self->comp_id,
+ _transport_str,
+ self->priority,
+ (tsk_strnullORempty(self->connection_addr) && self->socket) ? self->socket->ip : self->connection_addr,
+ (self->port <= 0 && self->socket) ? self->socket->port : self->port,
+ self->cand_type_str ? self->cand_type_str : _tnet_ice_candidate_get_candtype_str(self->type_e),
+ self->extension_att_list,
+ &self->tostring);
+
/* <rel-addr> and <rel-port>: convey transport addresses related to the
candidate, useful for diagnostics and other purposes. <rel-addr>
and <rel-port> MUST be present for server reflexive, peer
reflexive, and relayed candidates. */
- switch (self->type_e){
- case tnet_ice_cand_type_srflx:
- case tnet_ice_cand_type_prflx:
- case tnet_ice_cand_type_relay:
- {
- if (self->socket){ // when called from the browser(IE, Safari, Opera or Firefox) webrtc4all
- tsk_strcat_2(&self->tostring, " raddr %s rport %d", self->socket->ip, self->socket->port);
- }
- break;
- }
- default:
- {
- break;
+ switch (self->type_e) {
+ case tnet_ice_cand_type_srflx:
+ case tnet_ice_cand_type_prflx:
+ case tnet_ice_cand_type_relay: {
+ if (self->socket) { // when called from the browser(IE, Safari, Opera or Firefox) webrtc4all
+ tsk_strcat_2(&self->tostring, " raddr %s rport %d", self->socket->ip, self->socket->port);
}
+ break;
}
-
+ default: {
+ break;
+ }
+ }
+
// To ease debugging
if (self->socket) {
tsk_strcat_2(&self->tostring, " tr %s", _tnet_ice_candidate_get_transport_str(self->socket->type));
@@ -343,26 +336,26 @@ const char* tnet_ice_candidate_tostring(tnet_ice_candidate_t* self)
tsk_strcat_2(&self->tostring, " fd %d", self->socket->fd);
}
}
-
+
// WebRTC (Chrome) specific
if (self->is_ice_jingle) {
- if (!tsk_params_have_param(self->extension_att_list, "name")){
+ if (!tsk_params_have_param(self->extension_att_list, "name")) {
tsk_strcat_2(&self->tostring, " name %s", self->is_rtp ? (self->is_video ? "video_rtp" : "rtp") : (self->is_video ? "video_rtcp" : "rtcp"));
}
- if (!tsk_params_have_param(self->extension_att_list, "username")){
+ if (!tsk_params_have_param(self->extension_att_list, "username")) {
tsk_strcat_2(&self->tostring, " username %s", self->ufrag);
}
- if (!tsk_params_have_param(self->extension_att_list, "password")){
+ if (!tsk_params_have_param(self->extension_att_list, "password")) {
tsk_strcat_2(&self->tostring, " password %s", self->pwd);
}
- if (!tsk_params_have_param(self->extension_att_list, "network_name")){
+ if (!tsk_params_have_param(self->extension_att_list, "network_name")) {
tsk_strcat_2(&self->tostring, " network_name %s", "{9EBBE687-CCE6-42D3-87F5-B57BB30DEE23}");
}
- if (!tsk_params_have_param(self->extension_att_list, "generation")){
+ if (!tsk_params_have_param(self->extension_att_list, "generation")) {
tsk_strcat_2(&self->tostring, " generation %s", "0");
}
}
-
+
return self->tostring;
}
@@ -371,56 +364,56 @@ int tnet_ice_candidate_send_stun_bind_request(tnet_ice_candidate_t* self, const
tnet_stun_pkt_t *request = tsk_null;
tsk_buffer_t *buffer = tsk_null;
int ret, sendBytes;
-
- if (!self || !server_addr || !TNET_SOCKET_IS_VALID(self->socket)){
+
+ if (!self || !server_addr || !TNET_SOCKET_IS_VALID(self->socket)) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
request = _tnet_ice_candidate_stun_create_bind_request(self, username, password);
- if (!request){
+ if (!request) {
TSK_DEBUG_ERROR("Failed to create STUN request");
ret = -2;
goto bail;
}
-
- if ((ret = tnet_stun_pkt_write_with_padding_2(request, &buffer))){
+
+ if ((ret = tnet_stun_pkt_write_with_padding_2(request, &buffer))) {
TSK_DEBUG_ERROR("Failed to serialize STUN request");
goto bail;
}
-
+
sendBytes = tnet_sockfd_sendto(self->socket->fd, (const struct sockaddr*)server_addr, buffer->data, buffer->size);// return number of sent bytes
- if (sendBytes == buffer->size){
+ if (sendBytes == buffer->size) {
memcpy(self->stun.transac_id, request->transac_id, sizeof(tnet_stun_transac_id_t));
ret = 0;
}
- else{
+ else {
TSK_DEBUG_ERROR("Only %d bytes sent", sendBytes);
ret = -4;
goto bail;
}
-
+
bail:
TSK_OBJECT_SAFE_FREE(request);
TSK_OBJECT_SAFE_FREE(buffer);
-
+
return 0;
}
int tnet_ice_candidate_process_stun_response(tnet_ice_candidate_t* self, const tnet_stun_pkt_resp_t* response, tnet_fd_t fd)
{
int ret = 0;
-
- if (!self || !response){
+
+ if (!self || !response) {
TSK_DEBUG_ERROR("Inavlid parameter");
return -1;
}
-
+
//if(!(_tnet_ice_candidate_stun_transac_id_equals(response->transac_id, self->stun.transac_id))){
// TSK_DEBUG_ERROR("Transaction id mismatch");
// return -2;
//}
-
+
if (TNET_STUN_PKT_RESP_IS_ERROR(response)) {
uint16_t u_code;
if ((ret = tnet_stun_pkt_get_errorcode(response, &u_code))) {
@@ -452,7 +445,7 @@ int tnet_ice_candidate_process_stun_response(tnet_ice_candidate_t* self, const t
else if (TNET_STUN_PKT_RESP_IS_SUCCESS(response)) {
const tnet_stun_attr_address_t* pc_attr_addr;
if (((ret = tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_attr_addr)) == 0 && pc_attr_addr)
- || ((ret = tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t**)&pc_attr_addr)) == 0 && pc_attr_addr)) {
+ || ((ret = tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t**)&pc_attr_addr)) == 0 && pc_attr_addr)) {
tnet_ip_t ip;
if ((ret = tnet_stun_utils_inet_ntop((pc_attr_addr->e_family == tnet_stun_address_family_ipv6), &pc_attr_addr->address, &ip))) {
return ret;
@@ -461,7 +454,7 @@ int tnet_ice_candidate_process_stun_response(tnet_ice_candidate_t* self, const t
self->stun.srflx_port = pc_attr_addr->u_port;
}
}
-
+
return ret;
}
@@ -470,7 +463,7 @@ const tnet_ice_candidate_t* tnet_ice_candidate_find_by_fd(tnet_ice_candidates_L_
if (candidates) {
const tsk_list_item_t *item;
const tnet_ice_candidate_t* candidate;
-
+
tsk_list_lock(candidates);
tsk_list_foreach(item, candidates) {
if (!(candidate = item->data)) {
@@ -482,13 +475,13 @@ const tnet_ice_candidate_t* tnet_ice_candidate_find_by_fd(tnet_ice_candidates_L_
}
}
}
-
+
return tsk_null;
}
const char* tnet_ice_candidate_get_ufrag(const tnet_ice_candidate_t* self)
{
- if (self){
+ if (self) {
return self->ufrag ? self->ufrag : tnet_ice_candidate_get_att_value(self, "username");
}
return tsk_null;
@@ -496,22 +489,22 @@ const char* tnet_ice_candidate_get_ufrag(const tnet_ice_candidate_t* self)
const char* tnet_ice_candidate_get_pwd(const tnet_ice_candidate_t* self)
{
- if (self){
+ if (self) {
return self->pwd ? self->pwd : tnet_ice_candidate_get_att_value(self, "password");
}
return tsk_null;
}
static int _tnet_ice_candidate_tostring(
- uint8_t* foundation,
- uint32_t comp_id,
- const char* transport_str,
- uint32_t priority,
- const char* connection_addr,
- tnet_port_t port,
- const char* cand_type_str,
- const tsk_params_L_t *extension_att_list,
- char** output)
+ uint8_t* foundation,
+ uint32_t comp_id,
+ const char* transport_str,
+ uint32_t priority,
+ const char* connection_addr,
+ tnet_port_t port,
+ const char* cand_type_str,
+ const tsk_params_L_t *extension_att_list,
+ char** output)
{
if (!output) {
TSK_DEBUG_ERROR("Invalid argument");
@@ -525,10 +518,10 @@ static int _tnet_ice_candidate_tostring(
connection_addr,
port,
cand_type_str);
-
+
if (extension_att_list) {
const tsk_list_item_t *item;
- tsk_list_foreach(item, extension_att_list){
+ tsk_list_foreach(item, extension_att_list) {
tsk_strcat_2(output, " %s %s", TSK_PARAM(item->data)->name, TSK_PARAM(item->data)->value);
}
}
@@ -537,11 +530,16 @@ static int _tnet_ice_candidate_tostring(
static const char* _tnet_ice_candidate_get_foundation(tnet_ice_cand_type_t type)
{
- switch (type){
- case tnet_ice_cand_type_host: return TNET_ICE_CANDIDATE_FOUNDATION_HOST;
- case tnet_ice_cand_type_srflx: return TNET_ICE_CANDIDATE_FOUNDATION_SRFLX;
- case tnet_ice_cand_type_prflx: return TNET_ICE_CANDIDATE_FOUNDATION_PRFLX;
- case tnet_ice_cand_type_relay: default: return TNET_ICE_CANDIDATE_FOUNDATION_RELAY;
+ switch (type) {
+ case tnet_ice_cand_type_host:
+ return TNET_ICE_CANDIDATE_FOUNDATION_HOST;
+ case tnet_ice_cand_type_srflx:
+ return TNET_ICE_CANDIDATE_FOUNDATION_SRFLX;
+ case tnet_ice_cand_type_prflx:
+ return TNET_ICE_CANDIDATE_FOUNDATION_PRFLX;
+ case tnet_ice_cand_type_relay:
+ default:
+ return TNET_ICE_CANDIDATE_FOUNDATION_RELAY;
}
}
@@ -550,8 +548,8 @@ static tsk_bool_t _tnet_ice_candidate_stun_transac_id_equals(const tnet_stun_tra
{
tsk_size_t i;
static const tsk_size_t size = sizeof(tnet_stun_transac_id_t);
- for (i = 0; i < size; i++){
- if (id1[i] != id2[i]){
+ for (i = 0; i < size; i++) {
+ if (id1[i] != id2[i]) {
return tsk_false;
}
}
@@ -562,12 +560,12 @@ static tnet_stun_pkt_t * _tnet_ice_candidate_stun_create_bind_request(tnet_ice_c
{
tnet_stun_pkt_t *request = tsk_null;
int ret;
-
+
if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
+
if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, &request))) {
TSK_DEBUG_ERROR("Failed to create STUN Bind request");
goto bail;
@@ -585,7 +583,7 @@ static tnet_stun_pkt_t * _tnet_ice_candidate_stun_create_bind_request(tnet_ice_c
goto bail;
}
}
-
+
bail:
if (ret) {
TSK_OBJECT_SAFE_FREE(request);
@@ -606,7 +604,7 @@ return TNET_ICE_CANDIDATE_TRANSPORT_##STR; \
TRANSPORT_GET(WS);
TRANSPORT_GET(WSS);
return "UNKNOWN";
-
+
#undef TRANSPORT_GET
}
@@ -616,7 +614,7 @@ static tnet_socket_type_t _tnet_ice_candidate_get_transport_type(tsk_bool_t ipv6
if(tsk_striequals(TNET_ICE_CANDIDATE_TRANSPORT_##STR, transport_str)){ \
return tnet_socket_type_##str##_ipv4; \
}
-
+
TRANSPORT_GET(UDP, udp);
TRANSPORT_GET(TCP, tcp);
TRANSPORT_GET(TLS, tls);
@@ -624,37 +622,42 @@ return tnet_socket_type_##str##_ipv4; \
TRANSPORT_GET(WS, ws);
TRANSPORT_GET(WSS, wss);
return tnet_socket_type_invalid;
-
+
#undef TRANSPORT_GET
}
static const char* _tnet_ice_candidate_get_candtype_str(tnet_ice_cand_type_t candtype_e)
{
- switch (candtype_e){
- case tnet_ice_cand_type_unknown:
- default: return "unknown";
- case tnet_ice_cand_type_host: return TNET_ICE_CANDIDATE_TYPE_HOST;
- case tnet_ice_cand_type_srflx: return TNET_ICE_CANDIDATE_TYPE_SRFLX;
- case tnet_ice_cand_type_prflx: return TNET_ICE_CANDIDATE_TYPE_PRFLX;
- case tnet_ice_cand_type_relay: return TNET_ICE_CANDIDATE_TYPE_RELAY;
+ switch (candtype_e) {
+ case tnet_ice_cand_type_unknown:
+ default:
+ return "unknown";
+ case tnet_ice_cand_type_host:
+ return TNET_ICE_CANDIDATE_TYPE_HOST;
+ case tnet_ice_cand_type_srflx:
+ return TNET_ICE_CANDIDATE_TYPE_SRFLX;
+ case tnet_ice_cand_type_prflx:
+ return TNET_ICE_CANDIDATE_TYPE_PRFLX;
+ case tnet_ice_cand_type_relay:
+ return TNET_ICE_CANDIDATE_TYPE_RELAY;
}
}
static tnet_ice_cand_type_t _tnet_ice_candtype_get_transport_type(const char* candtype_str)
{
- if (tsk_striequals(TNET_ICE_CANDIDATE_TYPE_HOST, candtype_str)){
+ if (tsk_striequals(TNET_ICE_CANDIDATE_TYPE_HOST, candtype_str)) {
return tnet_ice_cand_type_host;
}
- else if (tsk_striequals(TNET_ICE_CANDIDATE_TYPE_SRFLX, candtype_str)){
+ else if (tsk_striequals(TNET_ICE_CANDIDATE_TYPE_SRFLX, candtype_str)) {
return tnet_ice_cand_type_srflx;
}
- else if (tsk_striequals(TNET_ICE_CANDIDATE_TYPE_PRFLX, candtype_str)){
+ else if (tsk_striequals(TNET_ICE_CANDIDATE_TYPE_PRFLX, candtype_str)) {
return tnet_ice_cand_type_prflx;
}
- else if (tsk_striequals(TNET_ICE_CANDIDATE_TYPE_RELAY, candtype_str)){
+ else if (tsk_striequals(TNET_ICE_CANDIDATE_TYPE_RELAY, candtype_str)) {
return tnet_ice_cand_type_relay;
}
- else{
+ else {
return tnet_ice_cand_type_unknown;
}
}
diff --git a/tinyNET/src/ice/tnet_ice_candidate.h b/tinyNET/src/ice/tnet_ice_candidate.h
index d2cb126..749192d 100755
--- a/tinyNET/src/ice/tnet_ice_candidate.h
+++ b/tinyNET/src/ice/tnet_ice_candidate.h
@@ -8,12 +8,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -59,54 +59,52 @@ TNET_BEGIN_DECLS
#define TNET_ICE_CANDIDATE_FOUND_SIZE_PREF 15
-typedef enum tnet_ice_cand_type_e
-{
- tnet_ice_cand_type_unknown,
- tnet_ice_cand_type_host,
- tnet_ice_cand_type_srflx,
- tnet_ice_cand_type_prflx,
- tnet_ice_cand_type_relay
+typedef enum tnet_ice_cand_type_e {
+ tnet_ice_cand_type_unknown,
+ tnet_ice_cand_type_host,
+ tnet_ice_cand_type_srflx,
+ tnet_ice_cand_type_prflx,
+ tnet_ice_cand_type_relay
}
tnet_ice_cand_type_t;
-typedef struct tnet_ice_candidate_s
-{
- TSK_DECLARE_OBJECT;
-
- tnet_ice_cand_type_t type_e;
- uint8_t foundation[33]; // 1*32ice-char
- uint32_t comp_id; // 1*5DIGIT
- char* transport_str; // "UP" / token
- enum tnet_socket_type_e transport_e;
- uint32_t priority; // 1*10DIGIST [1 - (2**31 - 1)]
- char* cand_type_str; // "host" / "srflx" / "prflx" / "relay" / "token"
- tnet_ip_t connection_addr;
- tnet_port_t port;
- tsk_params_L_t *extension_att_list;
-
- tsk_bool_t is_ice_jingle;
- tsk_bool_t is_rtp;
- tsk_bool_t is_video;
- uint16_t local_pref; // [0 - 65535]
-
- char* ufrag;
- char* pwd;
-
- struct tnet_socket_s* socket;
- struct{
- char* nonce;
- char* realm;
- char* srflx_addr;
- tnet_stun_transac_id_t transac_id;
- tnet_port_t srflx_port;
- } stun;
- struct {
- struct tnet_turn_session_s* ss;
- char* relay_addr;
- tnet_port_t relay_port;
- } turn;
-
- char *tostring;
+typedef struct tnet_ice_candidate_s {
+ TSK_DECLARE_OBJECT;
+
+ tnet_ice_cand_type_t type_e;
+ uint8_t foundation[33]; // 1*32ice-char
+ uint32_t comp_id; // 1*5DIGIT
+ char* transport_str; // "UP" / token
+ enum tnet_socket_type_e transport_e;
+ uint32_t priority; // 1*10DIGIST [1 - (2**31 - 1)]
+ char* cand_type_str; // "host" / "srflx" / "prflx" / "relay" / "token"
+ tnet_ip_t connection_addr;
+ tnet_port_t port;
+ tsk_params_L_t *extension_att_list;
+
+ tsk_bool_t is_ice_jingle;
+ tsk_bool_t is_rtp;
+ tsk_bool_t is_video;
+ uint16_t local_pref; // [0 - 65535]
+
+ char* ufrag;
+ char* pwd;
+
+ struct tnet_socket_s* socket;
+ struct {
+ char* nonce;
+ char* realm;
+ char* srflx_addr;
+ tnet_stun_transac_id_t transac_id;
+ tnet_port_t srflx_port;
+ } stun;
+ struct {
+ struct tnet_turn_session_s* ss;
+ char* relay_addr;
+ tnet_port_t relay_port;
+ } turn;
+
+ char *tostring;
}
tnet_ice_candidate_t;
diff --git a/tinyNET/src/ice/tnet_ice_ctx.c b/tinyNET/src/ice/tnet_ice_ctx.c
index 94d3042..6e5e5be 100755
--- a/tinyNET/src/ice/tnet_ice_ctx.c
+++ b/tinyNET/src/ice/tnet_ice_ctx.c
@@ -84,8 +84,7 @@ typedef tsk_list_t tnet_ice_servers_L_t;
static const char* foundation_default = tsk_null;
-typedef enum tnet_ice_server_proto_e
-{
+typedef enum tnet_ice_server_proto_e {
tnet_ice_server_proto_none = 0x00,
tnet_ice_server_proto_stun = (0x01 << 0),
tnet_ice_server_proto_turn = (0x01 << 1),
@@ -134,10 +133,9 @@ static int _tnet_ice_ctx_fsm_OnTerminated(struct tnet_ice_ctx_s* self);
static tsk_bool_t _tnet_ice_ctx_fsm_cond_NotStarted(struct tnet_ice_ctx_s* self, const void* _any);
static int _tnet_ice_ctx_turn_callback(const struct tnet_turn_session_event_xs *e);
-typedef struct tnet_ice_server_s
-{
+typedef struct tnet_ice_server_s {
TSK_DECLARE_OBJECT;
-
+
enum tnet_socket_type_e e_transport;
tnet_ice_server_proto_t e_proto;
char* str_server_addr;
@@ -165,13 +163,12 @@ static tsk_object_t* tnet_ice_server_dtor(tsk_object_t * self)
TSK_FREE(ice_server->str_software);
TSK_FREE(ice_server->str_username);
TSK_FREE(ice_server->str_password);
-
+
TSK_DEBUG_INFO("*** ICE server destroyed ***");
}
return self;
}
-static const tsk_object_def_t tnet_ice_server_def_s =
-{
+static const tsk_object_def_t tnet_ice_server_def_s = {
sizeof(tnet_ice_server_t),
tnet_ice_server_ctor,
tnet_ice_server_dtor,
@@ -179,25 +176,25 @@ static const tsk_object_def_t tnet_ice_server_def_s =
};
static tnet_ice_server_t* tnet_ice_server_create(
- enum tnet_ice_server_proto_e e_proto,
- enum tnet_socket_type_e e_transport,
- const char* str_server_addr, uint16_t u_server_port,
- const char* str_software,
- const char* str_username, const char* str_password)
+ enum tnet_ice_server_proto_e e_proto,
+ enum tnet_socket_type_e e_transport,
+ const char* str_server_addr, uint16_t u_server_port,
+ const char* str_software,
+ const char* str_username, const char* str_password)
{
tnet_ice_server_t *ice_server;
struct sockaddr_storage obj_server_addr;
-
+
if (tsk_strnullORempty(str_server_addr) || !u_server_port) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
+
if (tnet_sockaddr_init(str_server_addr, u_server_port, e_transport, &obj_server_addr) != 0) {
TSK_DEBUG_ERROR("Invalid server address (host=%s, port=%d, transport=%d)", str_server_addr, u_server_port, e_transport);
return tsk_null;
}
-
+
if ((ice_server = tsk_object_new(&tnet_ice_server_def_s))) {
ice_server->e_proto = e_proto;
ice_server->e_transport = e_transport;
@@ -211,10 +208,9 @@ static tnet_ice_server_t* tnet_ice_server_create(
return ice_server;
}
-typedef struct tnet_ice_ctx_s
-{
+typedef struct tnet_ice_ctx_s {
TSK_DECLARE_RUNNABLE;
-
+
tsk_bool_t is_started;
tsk_bool_t is_active;
tsk_bool_t is_sync_mode;
@@ -229,7 +225,7 @@ typedef struct tnet_ice_ctx_s
tsk_bool_t unicast;
tsk_bool_t anycast;
tsk_bool_t multicast;
-
+
tsk_bool_t is_connchecking;
tsk_bool_t is_controlling;
tsk_bool_t is_ice_jingle;
@@ -237,19 +233,19 @@ typedef struct tnet_ice_ctx_s
tsk_bool_t is_stun_enabled;
uint64_t tie_breaker;
uint64_t concheck_timeout;
-
+
const void* rtp_callback_data;
tnet_ice_rtp_callback_f rtp_callback;
-
+
tnet_ice_servers_L_t *servers;
-
+
char* ufrag;
char* pwd;
-
+
tsk_timer_manager_handle_t* h_timer_mgr;
-
+
tsk_fsm_t* fsm;
-
+
tsk_condwait_handle_t* condwait_pairs;
tnet_ice_candidates_L_t* candidates_local;
tnet_ice_candidates_L_t* candidates_remote;
@@ -257,23 +253,23 @@ typedef struct tnet_ice_ctx_s
tsk_bool_t have_nominated_offer;
tsk_bool_t have_nominated_answer;
tsk_bool_t have_nominated_symetric; /**< Whether symetic RTP has been negotiated */
-
+
uint16_t RTO; /**< Estimate of the round-trip time (RTT) in millisecond */
uint16_t Rc; /**< Number of retransmissions for UDP in millisecond */
-
+
struct {
char* path_priv;
char* path_pub;
char* path_ca;
tsk_bool_t verify;
} ssl;
-
+
struct {
tsk_bool_t auto_detect;
struct tnet_proxyinfo_s* info;
}
proxy;
-
+
struct {
tsk_condwait_handle_t* condwait;
struct tnet_turn_session_s* ss_nominated_rtp;
@@ -281,21 +277,19 @@ typedef struct tnet_ice_ctx_s
struct tnet_turn_session_s* ss_nominated_rtcp;
tnet_turn_peer_id_t peer_id_rtcp;
} turn;
-
+
TSK_DECLARE_SAFEOBJ;
}
tnet_ice_ctx_t;
-typedef struct tnet_ice_action_s
-{
+typedef struct tnet_ice_action_s {
TSK_DECLARE_OBJECT;
-
+
tsk_fsm_action_id id;
}
tnet_ice_action_t;
-typedef enum _fsm_state_e
-{
+typedef enum _fsm_state_e {
_fsm_state_Started,
_fsm_state_GatheringHostCandidates,
_fsm_state_GatheringHostCandidatesDone,
@@ -310,8 +304,7 @@ typedef enum _fsm_state_e
}
_fsm_state_t;
-typedef enum _fsm_action_e
-{
+typedef enum _fsm_action_e {
_fsm_action_Success,
_fsm_action_Failure,
_fsm_action_GatherHostCandidates,
@@ -327,19 +320,18 @@ _fsm_action_t;
static tsk_object_t* tnet_ice_action_ctor(tsk_object_t * self, va_list * app)
{
tnet_ice_action_t *action = self;
- if (action){
+ if (action) {
}
return self;
}
static tsk_object_t* tnet_ice_action_dtor(tsk_object_t * self)
{
tnet_ice_action_t *action = self;
- if (action){
+ if (action) {
}
return self;
}
-static const tsk_object_def_t tnet_ice_action_def_s =
-{
+static const tsk_object_def_t tnet_ice_action_def_s = {
sizeof(tnet_ice_action_t),
tnet_ice_action_ctor,
tnet_ice_action_dtor,
@@ -348,7 +340,7 @@ static const tsk_object_def_t tnet_ice_action_def_s =
static tnet_ice_action_t* tnet_ice_action_create(tsk_fsm_action_id id)
{
tnet_ice_action_t *action = tsk_object_new(&tnet_ice_action_def_s);
- if (action){
+ if (action) {
action->id = id;
}
return action;
@@ -360,59 +352,59 @@ static tnet_ice_action_t* tnet_ice_action_create(tsk_fsm_action_id id)
static tsk_object_t* tnet_ice_ctx_ctor(tsk_object_t * self, va_list * app)
{
tnet_ice_ctx_t *ctx = self;
- if (ctx){
+ if (ctx) {
tsk_safeobj_init(ctx);
-
- if (!(ctx->h_timer_mgr = tsk_timer_manager_create())){
+
+ if (!(ctx->h_timer_mgr = tsk_timer_manager_create())) {
TSK_DEBUG_ERROR("Failed to create timer manager");
return tsk_null;
}
- if (!(ctx->fsm = tsk_fsm_create(_fsm_state_Started, _fsm_state_Terminated))){
+ if (!(ctx->fsm = tsk_fsm_create(_fsm_state_Started, _fsm_state_Terminated))) {
TSK_DEBUG_ERROR("Failed to create state machine");
return tsk_null;
}
- if (!(ctx->candidates_local = tsk_list_create())){
+ if (!(ctx->candidates_local = tsk_list_create())) {
TSK_DEBUG_ERROR("Failed to create candidates list");
return tsk_null;
}
- if (!(ctx->candidates_remote = tsk_list_create())){
+ if (!(ctx->candidates_remote = tsk_list_create())) {
TSK_DEBUG_ERROR("Failed to create candidates list");
return tsk_null;
}
- if (!(ctx->candidates_pairs = tsk_list_create())){
+ if (!(ctx->candidates_pairs = tsk_list_create())) {
TSK_DEBUG_ERROR("Failed to create candidates list");
return tsk_null;
}
-
+
// Create condwait for pairs
if (!(ctx->condwait_pairs = tsk_condwait_create())) {
TSK_DEBUG_ERROR("Failed to create condwait for pairs");
return tsk_null;
}
-
+
// Create list objects to hold the servers
- if (!(ctx->servers = tsk_list_create())){
+ if (!(ctx->servers = tsk_list_create())) {
TSK_DEBUG_ERROR("Failed to create server list");
return tsk_null;
}
-
+
tsk_runnable_set_important(TSK_RUNNABLE(self), tsk_false);
-
+
/* 7.2.1. Sending over UDP
In fixed-line access links, a value of 500 ms is RECOMMENDED.
*/
ctx->RTO = kIceDefaultRTO;
-
+
/* 7.2.1. Sending over UDP
Rc SHOULD be configurable and SHOULD have a default of 7.
*/
ctx->Rc = kIceDefaultRC;
-
+
ctx->tie_breaker = ((tsk_time_now() << 32) ^ tsk_time_now());
ctx->is_ice_jingle = tsk_false;
ctx->is_stun_enabled = kIceDefaultStunEnabled;
ctx->is_turn_enabled = kIceDefaultTurnEnabled;
-
+
ctx->concheck_timeout = LONG_MAX;
}
return self;
@@ -420,17 +412,17 @@ static tsk_object_t* tnet_ice_ctx_ctor(tsk_object_t * self, va_list * app)
static tsk_object_t* tnet_ice_ctx_dtor(tsk_object_t * self)
{
tnet_ice_ctx_t *ctx = self;
- if (ctx){
+ if (ctx) {
tnet_ice_ctx_stop(ctx);
- if (ctx->h_timer_mgr){
+ if (ctx->h_timer_mgr) {
tsk_timer_manager_destroy(&ctx->h_timer_mgr);
}
-
+
TSK_OBJECT_SAFE_FREE(ctx->fsm);
TSK_OBJECT_SAFE_FREE(ctx->candidates_local);
TSK_OBJECT_SAFE_FREE(ctx->candidates_remote);
TSK_OBJECT_SAFE_FREE(ctx->candidates_pairs);
-
+
TSK_OBJECT_SAFE_FREE(ctx->turn.ss_nominated_rtp);
TSK_OBJECT_SAFE_FREE(ctx->turn.ss_nominated_rtcp);
if (ctx->turn.condwait) {
@@ -440,20 +432,19 @@ static tsk_object_t* tnet_ice_ctx_dtor(tsk_object_t * self)
tsk_condwait_destroy(&ctx->condwait_pairs);
}
TSK_OBJECT_SAFE_FREE(ctx->servers);
-
+
TSK_OBJECT_SAFE_FREE(ctx->proxy.info);
-
+
TSK_FREE(ctx->ssl.path_priv);
TSK_FREE(ctx->ssl.path_pub);
TSK_FREE(ctx->ssl.path_ca);
-
+
tsk_safeobj_deinit(ctx);
}
TSK_DEBUG_INFO("*** ICE context destroyed ***");
return self;
}
-static const tsk_object_def_t tnet_ice_ctx_def_s =
-{
+static const tsk_object_def_t tnet_ice_ctx_def_s = {
sizeof(tnet_ice_ctx_t),
tnet_ice_ctx_ctor,
tnet_ice_ctx_dtor,
@@ -464,12 +455,12 @@ static const tsk_object_def_t tnet_ice_ctx_def_s =
tnet_ice_ctx_t* tnet_ice_ctx_create(tsk_bool_t is_ice_jingle, tsk_bool_t use_ipv6, tsk_bool_t use_rtcp, tsk_bool_t is_video, tnet_ice_callback_f callback, const void* userdata)
{
tnet_ice_ctx_t* ctx;
-
- if (!(ctx = tsk_object_new(&tnet_ice_ctx_def_s))){
+
+ if (!(ctx = tsk_object_new(&tnet_ice_ctx_def_s))) {
TSK_DEBUG_ERROR("Failed to create ICE context object");
return tsk_null;
}
-
+
ctx->is_ice_jingle = is_ice_jingle;
ctx->use_ipv6 = use_ipv6;
ctx->use_rtcp = use_rtcp;
@@ -479,10 +470,10 @@ tnet_ice_ctx_t* tnet_ice_ctx_create(tsk_bool_t is_ice_jingle, tsk_bool_t use_ipv
ctx->unicast = tsk_true;
ctx->anycast = tsk_false;
ctx->multicast = tsk_false;
-
+
tnet_ice_utils_set_ufrag(&ctx->ufrag);
tnet_ice_utils_set_pwd(&ctx->pwd);
-
+
ctx->fsm->debug = TNET_ICE_DEBUG_STATE_MACHINE;
tsk_fsm_set_callback_terminated(ctx->fsm, TSK_FSM_ONTERMINATED_F(_tnet_ice_ctx_fsm_OnTerminated), (const void*)ctx);
tsk_fsm_set(ctx->fsm,
@@ -492,14 +483,14 @@ tnet_ice_ctx_t* tnet_ice_ctx_create(tsk_bool_t is_ice_jingle, tsk_bool_t use_ipv
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringHostCandidates, _fsm_action_Success, _fsm_state_GatheringHostCandidatesDone, _tnet_ice_ctx_fsm_GatheringHostCandidates_2_GatheringHostCandidatesDone_X_Success, "ICE_GatheringHostCandidates_2_GatheringHostCandidatesDone_X_Success"),
// (GatheringHostCandidates) -> (Failure) -> (Terminated)
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringHostCandidates, _fsm_action_Failure, _fsm_state_Terminated, _tnet_ice_ctx_fsm_GatheringHostCandidates_2_Terminated_X_Failure, "ICE_GatheringHostCandidates_2_Terminated_X_Failure"),
-
+
// (GatheringHostCandidatesDone) -> (GatherReflexiveCandidates) -> (GatheringReflexiveCandidates)
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringHostCandidatesDone, _fsm_action_GatherReflexiveCandidates, _fsm_state_GatheringReflexiveCandidates, _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCandidates_X_GatherReflexiveCandidates, "ICE_GatheringHostCandidatesDone_2_GatheringReflexiveCandidates_X_GatherReflexiveCandidates"),
// (GatheringReflexiveCandidates) -> (Success) -> GatheringReflexiveCandidatesDone
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringReflexiveCandidates, _fsm_action_Success, _fsm_state_GatheringReflexiveCandidatesDone, _tnet_ice_ctx_fsm_GatheringReflexiveCandidates_2_GatheringReflexiveCandidatesDone_X_Success, "ICE_fsm_GatheringReflexiveCandidates_2_GatheringReflexiveCandidatesDone_X_Success"),
// (GatheringReflexiveCandidates) -> (Failure) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringReflexiveCandidates, _fsm_action_Failure, _fsm_state_Terminated, _tnet_ice_ctx_fsm_GatheringReflexiveCandidates_2_Terminated_X_Failure, "ICE_GatheringReflexiveCandidates_2_Terminated_X_Failure"),
-
+
// (GatheringReflexiveCandidatesDone) -> (GatherRelayCandidates) -> (GatheringRelayCandidates)
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringReflexiveCandidatesDone, _fsm_action_GatherRelayCandidates, _fsm_state_GatheringRelayCandidates, _tnet_ice_ctx_fsm_GatheringReflexiveCandidatesDone_2_GatheringRelayCandidates_X_GatherRelayCandidates, "ICE_GatheringReflexiveCandidatesDone_2_GatheringRelayCandidates_X_GatherRelayCandidates"),
// (GatheringHostCandidatesDone) -> (GatherRelayCandidates) -> (GatheringRelayCandidates)
@@ -508,28 +499,28 @@ tnet_ice_ctx_t* tnet_ice_ctx_create(tsk_bool_t is_ice_jingle, tsk_bool_t use_ipv
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringRelayCandidates, _fsm_action_Success, _fsm_state_GatheringRelayCandidatesDone, _tnet_ice_ctx_fsm_GatheringRelayCandidates_2_GatheringRelayCandidatesDone_X_Success, "ICE_fsm_GatheringRelayCandidates_2_GatheringRelayCandidatesDone_X_Success"),
// (GatheringRelayCandidates) -> (Failure) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringRelayCandidates, _fsm_action_Failure, _fsm_state_Terminated, _tnet_ice_ctx_fsm_GatheringRelayCandidates_2_Terminated_X_Failure, "ICE_GatheringRelayCandidates_2_Terminated_X_Failure"),
-
+
// (GatheringComplet) -> (ConnCheck) -> ConnChecking
TSK_FSM_ADD_ALWAYS(_fsm_state_GatheringCompleted, _fsm_action_ConnCheck, _fsm_state_ConnChecking, _tnet_ice_ctx_fsm_GatheringCompleted_2_ConnChecking_X_ConnCheck, "ICE_GatheringCompleted_2_ConnChecking_X_ConnCheck"),
// (ConnChecking) -> (Success) -> ConnCheckingCompleted
TSK_FSM_ADD_ALWAYS(_fsm_state_ConnChecking, _fsm_action_Success, _fsm_state_ConnCheckingCompleted, _tnet_ice_ctx_fsm_ConnChecking_2_ConnCheckingCompleted_X_Success, "ICE_ConnChecking_2_ConnCheckingCompleted_X_Success"),
// (ConnChecking) -> (Failure) -> Terminated
TSK_FSM_ADD_ALWAYS(_fsm_state_ConnChecking, _fsm_action_Failure, _fsm_state_Terminated, _tnet_ice_ctx_fsm_ConnChecking_2_Terminated_X_Failure, "ICE_ConnChecking_2_Terminated_X_Failure"),
-
+
// (Any) -> (GatheringComplet) -> GatheringCompleted
TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_GatheringComplet, _fsm_state_GatheringCompleted, _tnet_ice_ctx_fsm_Any_2_GatheringCompleted_X_GatheringComplet, "ICE_Any_2_GatheringCompleted_X_GatheringComplet"),
// (Any) -> (Cancel) -> Started
TSK_FSM_ADD_ALWAYS(tsk_fsm_state_any, _fsm_action_Cancel, _fsm_state_Started, _tnet_ice_ctx_fsm_Any_2_Started_X_Cancel, "ICE_Any_2_Started_X_Cancel"),
// (Any) -> (AnyNotStarted) -> Terminated
TSK_FSM_ADD(tsk_fsm_state_any, tsk_fsm_action_any, _tnet_ice_ctx_fsm_cond_NotStarted, _fsm_state_Terminated, _tnet_ice_ctx_fsm_Any_2_Terminated_X_AnyNotStarted, "ICE_fsm_Any_2_Terminated_X_AnyNotStarted")
- );
-
+ );
+
return ctx;
}
int tnet_ice_ctx_set_userdata(tnet_ice_ctx_t* self, const void* userdata)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -539,34 +530,34 @@ int tnet_ice_ctx_set_userdata(tnet_ice_ctx_t* self, const void* userdata)
// @deprecated: use "tnet_ice_ctx_add_server()"
int tnet_ice_ctx_set_stun(
- tnet_ice_ctx_t* self,
- const char* server_addr,
- uint16_t server_port,
- const char* software,
- const char* username,
- const char* password)
+ tnet_ice_ctx_t* self,
+ const char* server_addr,
+ uint16_t server_port,
+ const char* software,
+ const char* username,
+ const char* password)
{
_tnet_ice_ctx_servers_clear(self);
return tnet_ice_ctx_add_server(
- self,
- "udp",
- server_addr,
- server_port,
- (!tsk_strnullORempty(username) && !tsk_strnullORempty(password)), /* use_turn*/
- tsk_true, /* use_stun*/
- username,
- password);
+ self,
+ "udp",
+ server_addr,
+ server_port,
+ (!tsk_strnullORempty(username) && !tsk_strnullORempty(password)), /* use_turn*/
+ tsk_true, /* use_stun*/
+ username,
+ password);
}
int tnet_ice_ctx_add_server(
- struct tnet_ice_ctx_s* self,
- const char* transport_proto, // "udp", "tcp", "tls", "ws", "wss"
- const char* server_addr,
- uint16_t server_port,
- tsk_bool_t use_turn,
- tsk_bool_t use_stun,
- const char* username,
- const char* password)
+ struct tnet_ice_ctx_s* self,
+ const char* transport_proto, // "udp", "tcp", "tls", "ws", "wss"
+ const char* server_addr,
+ uint16_t server_port,
+ tsk_bool_t use_turn,
+ tsk_bool_t use_stun,
+ const char* username,
+ const char* password)
{
tnet_socket_type_t socket_type;
tnet_ice_server_proto_t e_proto = tnet_ice_server_proto_none;
@@ -584,7 +575,7 @@ int tnet_ice_ctx_add_server(
if (use_turn) {
e_proto |= tnet_ice_server_proto_turn;
}
-
+
if (tsk_striequals(transport_proto, "udp")) {
socket_type = self->use_ipv6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4;
}
@@ -612,7 +603,7 @@ int tnet_ice_ctx_add_server(
int tnet_ice_ctx_set_sync_mode(tnet_ice_ctx_t* self, tsk_bool_t sync_mode)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -622,7 +613,7 @@ int tnet_ice_ctx_set_sync_mode(tnet_ice_ctx_t* self, tsk_bool_t sync_mode)
int tnet_ice_ctx_set_silent_mode(struct tnet_ice_ctx_s* self, tsk_bool_t silent_mode)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -633,7 +624,7 @@ int tnet_ice_ctx_set_silent_mode(struct tnet_ice_ctx_s* self, tsk_bool_t silent_
// Whether to gather reflexive candidates
int tnet_ice_ctx_set_stun_enabled(struct tnet_ice_ctx_s* self, tsk_bool_t stun_enabled)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -644,7 +635,7 @@ int tnet_ice_ctx_set_stun_enabled(struct tnet_ice_ctx_s* self, tsk_bool_t stun_e
// Whether to gather relay candidates
int tnet_ice_ctx_set_turn_enabled(struct tnet_ice_ctx_s* self, tsk_bool_t turn_enabled)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -658,19 +649,19 @@ int tnet_ice_ctx_start(tnet_ice_ctx_t* self)
tsk_bool_t timer_mgr_started = tsk_false;
tsk_bool_t runnable_started = tsk_false;
const char* err = tsk_null;
-
- if (!self){
+
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
tsk_safeobj_lock(self);
-
+
TSK_DEBUG_INFO("tnet_ice_ctx_start");
-
- if (self->is_started){
+
+ if (self->is_started) {
ret = 0;
- if (!self->is_active){
+ if (!self->is_active) {
TSK_DEBUG_INFO("ICE restart");
ret = _tnet_ice_ctx_restart(self);
}
@@ -678,42 +669,42 @@ int tnet_ice_ctx_start(tnet_ice_ctx_t* self)
tsk_safeobj_unlock(self);
return ret;
}
-
+
/* === Timer manager === */
- if ((ret = tsk_timer_manager_start(self->h_timer_mgr))){
+ if ((ret = tsk_timer_manager_start(self->h_timer_mgr))) {
err = "Failed to start timer manager";
TSK_DEBUG_ERROR("%s", err);
goto bail;
}
timer_mgr_started = tsk_true;
-
+
/* === Runnable === */
TSK_RUNNABLE(self)->run = _tnet_ice_ctx_run;
- if ((ret = tsk_runnable_start(TSK_RUNNABLE(self), tnet_ice_event_def_t))){
+ if ((ret = tsk_runnable_start(TSK_RUNNABLE(self), tnet_ice_event_def_t))) {
err = "Failed to start runnable";
TSK_DEBUG_ERROR("%s", err);
goto bail;
}
runnable_started = tsk_true;
-
+
self->is_started = tsk_true; // needed by FSM -> "Must" be before fsm_ast()
self->is_active = tsk_true;
-
- if ((ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_GatherHostCandidates))){
+
+ if ((ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_GatherHostCandidates))) {
err = "FSM execution failed";
TSK_DEBUG_ERROR("%s", err);
goto bail;
}
-
+
bail:
tsk_safeobj_unlock(self);
-
- if (ret){
+
+ if (ret) {
_tnet_ice_ctx_signal_async(self, tnet_ice_event_type_start_failed, err);
- if (timer_mgr_started){
+ if (timer_mgr_started) {
tsk_timer_manager_stop(self->h_timer_mgr);
}
- if (runnable_started){
+ if (runnable_started) {
tsk_runnable_stop(TSK_RUNNABLE(self));
}
self->is_started = tsk_false;
@@ -725,11 +716,11 @@ bail:
// register callback to call when we receive early RTP packets while negotaiating ICE pairs
int tnet_ice_ctx_rtp_callback(tnet_ice_ctx_t* self, tnet_ice_rtp_callback_f rtp_callback, const void* rtp_callback_data)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
self->rtp_callback_data = rtp_callback_data;
self->rtp_callback = rtp_callback;
return 0;
@@ -738,13 +729,13 @@ int tnet_ice_ctx_rtp_callback(tnet_ice_ctx_t* self, tnet_ice_rtp_callback_f rtp_
// timeout (millis): <=0 to disable
int tnet_ice_ctx_set_concheck_timeout(tnet_ice_ctx_t* self, int64_t timeout)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
self->concheck_timeout = (timeout <= 0 ? LONG_MAX : timeout);
-
+
return 0;
}
@@ -761,34 +752,34 @@ int tnet_ice_ctx_set_remote_candidates_2(struct tnet_ice_ctx_s* self, const char
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
self->is_controlling = is_controlling;
self->is_ice_jingle = is_ice_jingle;
tnet_ice_ctx_set_rtcpmux(self, use_rtcpmux);
-
+
if (tsk_strnullORempty(candidates)) {
// remote party is ICE-lite or doesn't support ICE
return tnet_ice_ctx_cancel(self);
}
-
+
TSK_DEBUG_INFO("tnet_ice_ctx_set_remote_candidates(ufrag=%s, pwd=%s, is_controlling=%d, is_ice_jingle=%d, use_rtcpmux=%d)",
ufrag, pwd, is_controlling, is_ice_jingle, use_rtcpmux);
-
+
tsk_list_lock(self->candidates_pairs);
if (!TSK_LIST_IS_EMPTY(self->candidates_pairs)) {
TSK_DEBUG_WARN("Adding Remote ICE candidates after pairs building");
}
tsk_list_unlock(self->candidates_pairs);
-
+
// active if remote is full-ICE
// in all case we are always full-ICE
// self->is_active = tsk_true;
-
+
tsk_list_lock(self->candidates_remote);
-
+
// clear old candidates
tsk_list_clear_items(self->candidates_remote);
-
+
copy = tsk_strdup(candidates);
size = (tsk_size_t)tsk_strlen(copy);
do {
@@ -819,13 +810,14 @@ int tnet_ice_ctx_set_remote_candidates_2(struct tnet_ice_ctx_s* self, const char
}
TSK_OBJECT_SAFE_FREE(candidate);
}
- } while (v && (idx < size));
-
+ }
+ while (v && (idx < size));
+
tsk_list_unlock(self->candidates_remote);
-
+
TSK_FREE(copy);
TSK_OBJECT_SAFE_FREE(added_candidates);
-
+
if (!tnet_ice_ctx_is_connected(self) && tnet_ice_ctx_got_local_candidates(self) && !TSK_LIST_IS_EMPTY(self->candidates_remote)) {
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_ConnCheck);
}
@@ -866,7 +858,7 @@ int tnet_ice_ctx_set_ssl_certs(struct tnet_ice_ctx_s* self, const char* path_pri
tsk_size_t tnet_ice_ctx_count_local_candidates(const tnet_ice_ctx_t* self)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return 0;
}
@@ -876,16 +868,16 @@ tsk_size_t tnet_ice_ctx_count_local_candidates(const tnet_ice_ctx_t* self)
tsk_bool_t tnet_ice_ctx_got_local_candidates(const tnet_ice_ctx_t* self)
{
tsk_fsm_state_id curr_state;
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_false;
}
- if (!self->is_started){
+ if (!self->is_started) {
return tsk_false;
}
-
+
curr_state = tsk_fsm_get_current_state(self->fsm);
-
+
return (curr_state >= _fsm_state_GatheringCompleted && curr_state < _fsm_state_Terminated);
}
@@ -893,13 +885,13 @@ const tnet_ice_candidate_t* tnet_ice_ctx_get_local_candidate_at(const tnet_ice_c
{
const tsk_list_item_t *item;
tsk_size_t pos = 0;
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
- tsk_list_foreach(item, self->candidates_local){
- if (pos++ == index){
+
+ tsk_list_foreach(item, self->candidates_local) {
+ if (pos++ == index) {
return (const tnet_ice_candidate_t*)item->data;
}
}
@@ -922,9 +914,9 @@ tsk_bool_t tnet_ice_ctx_is_turn_rtp_active(const struct tnet_ice_ctx_s* self)
{
tsk_bool_t b_active;
return tnet_ice_ctx_is_active(self)
- && self->turn.ss_nominated_rtp
- && tnet_turn_session_is_active(self->turn.ss_nominated_rtp, self->turn.peer_id_rtp, &b_active) == 0
- && b_active;
+ && self->turn.ss_nominated_rtp
+ && tnet_turn_session_is_active(self->turn.ss_nominated_rtp, self->turn.peer_id_rtp, &b_active) == 0
+ && b_active;
}
tsk_bool_t tnet_ice_ctx_is_turn_rtcp_active(const struct tnet_ice_ctx_s* self)
@@ -935,9 +927,9 @@ tsk_bool_t tnet_ice_ctx_is_turn_rtcp_active(const struct tnet_ice_ctx_s* self)
else {
tsk_bool_t b_active;
return tnet_ice_ctx_is_active(self)
- && self->turn.ss_nominated_rtcp
- && tnet_turn_session_is_active(self->turn.ss_nominated_rtcp, self->turn.peer_id_rtcp, &b_active) == 0
- && b_active;
+ && self->turn.ss_nominated_rtcp
+ && tnet_turn_session_is_active(self->turn.ss_nominated_rtcp, self->turn.peer_id_rtcp, &b_active) == 0
+ && b_active;
}
}
@@ -968,11 +960,11 @@ tsk_bool_t tnet_ice_ctx_use_rtcp(const tnet_ice_ctx_t* self)
}
int tnet_ice_ctx_get_nominated_symetric_candidates(const tnet_ice_ctx_t* self, uint32_t comp_id,
- const tnet_ice_candidate_t** candidate_offer,
- const tnet_ice_candidate_t** candidate_answer_src,
- const tnet_ice_candidate_t** candidate_answer_dest)
+ const tnet_ice_candidate_t** candidate_offer,
+ const tnet_ice_candidate_t** candidate_answer_src,
+ const tnet_ice_candidate_t** candidate_answer_dest)
{
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -993,14 +985,14 @@ int tnet_ice_ctx_send_turn_rtp(struct tnet_ice_ctx_s* self, const void* data, ts
int tnet_ice_ctx_send_turn_rtcp(struct tnet_ice_ctx_s* self, const void* data, tsk_size_t size)
{
return self->use_rtcpmux
- ? tnet_ice_ctx_send_turn_rtp(self, data, size)
- : _tnet_ice_ctx_send_turn_raw(self, self->turn.ss_nominated_rtcp, self->turn.peer_id_rtcp, data, size);
+ ? tnet_ice_ctx_send_turn_rtp(self, data, size)
+ : _tnet_ice_ctx_send_turn_raw(self, self->turn.ss_nominated_rtcp, self->turn.peer_id_rtcp, data, size);
}
int tnet_ice_ctx_turn_get_bytes_count(const struct tnet_ice_ctx_s* self, uint64_t* bytes_in, uint64_t* bytes_out)
{
int ret;
-
+
if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
@@ -1010,8 +1002,12 @@ int tnet_ice_ctx_turn_get_bytes_count(const struct tnet_ice_ctx_s* self, uint64_
uint64_t _bytes_in, _bytes_out;
ret = tnet_turn_session_get_bytes_count(self->turn.ss_nominated_rtcp, &_bytes_in, &_bytes_out);
if (ret == 0) {
- if (bytes_in) *bytes_in += _bytes_in;
- if (bytes_out) *bytes_out += _bytes_out;
+ if (bytes_in) {
+ *bytes_in += _bytes_in;
+ }
+ if (bytes_out) {
+ *bytes_out += _bytes_out;
+ }
}
}
return ret;
@@ -1058,19 +1054,19 @@ int tnet_ice_ctx_set_proxy_info(struct tnet_ice_ctx_s* self, enum tnet_proxy_typ
int tnet_ice_ctx_cancel(tnet_ice_ctx_t* self)
{
int ret;
-
+
if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
tsk_safeobj_lock(self);
if (tsk_fsm_get_current_state(self->fsm) == _fsm_state_Started) {
// Do nothing if already in the "started" state
ret = 0;
goto bail;
}
-
+
self->is_active = tsk_false;
self->have_nominated_symetric = tsk_false;
self->have_nominated_answer = tsk_false;
@@ -1080,7 +1076,7 @@ int tnet_ice_ctx_cancel(tnet_ice_ctx_t* self)
ret = tsk_condwait_broadcast(self->turn.condwait);
}
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_Cancel);
-
+
bail:
tsk_safeobj_unlock(self);
return ret;
@@ -1089,18 +1085,18 @@ bail:
int tnet_ice_ctx_stop(tnet_ice_ctx_t* self)
{
int ret;
-
+
if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
tsk_safeobj_lock(self);
if (!self->is_started) {
ret = 0;
goto bail;
}
-
+
self->is_started = tsk_false;
tsk_condwait_broadcast(self->condwait_pairs);
if (self->turn.condwait) {
@@ -1108,7 +1104,7 @@ int tnet_ice_ctx_stop(tnet_ice_ctx_t* self)
}
ret = tsk_timer_manager_stop(self->h_timer_mgr);
ret = tsk_runnable_stop(TSK_RUNNABLE(self));
-
+
bail:
tsk_safeobj_unlock(self);
return ret;
@@ -1136,92 +1132,92 @@ static int _tnet_ice_ctx_fsm_Started_2_GatheringHostCandidates_X_GatherHostCandi
static const tsk_bool_t dnsserver = tsk_false;
static const long if_index_any = -1; // any interface
static const char* destination = "doubango.org";
-
+
self = va_arg(*app, tnet_ice_ctx_t *);
socket_type = self->use_ipv6 ? tnet_socket_type_udp_ipv6 : tnet_socket_type_udp_ipv4;
-
+
addresses = tnet_get_addresses((self->use_ipv6 ? AF_INET6 : AF_INET), self->unicast, self->anycast, self->multicast, dnsserver, if_index_any);
- if (!addresses || TSK_LIST_IS_EMPTY(addresses)){
+ if (!addresses || TSK_LIST_IS_EMPTY(addresses)) {
TSK_DEBUG_ERROR("Failed to get addresses");
ret = -1;
goto bail;
}
-
-
+
+
check_best_local_ip = (tnet_getbestsource(destination, 5060, socket_type, &best_local_ip) == 0);
curr_local_pref = local_pref = check_best_local_ip ? 0xFFFE : 0xFFFF;
-
+
// lock-list
tsk_list_lock(self->candidates_local);
// clear-list
tsk_list_clear_items(self->candidates_local);
-
- tsk_list_foreach(item, addresses){
- if (!(address = item->data)){
+
+ tsk_list_foreach(item, addresses) {
+ if (!(address = item->data)) {
continue;
}
-
+
// Skip loopback address to avoid problems :)
- if ((address->family == AF_INET && tsk_striequals(address->ip, "127.0.0.1")) || (address->family == AF_INET6 && tsk_striequals(address->ip, "::1"))){
+ if ((address->family == AF_INET && tsk_striequals(address->ip, "127.0.0.1")) || (address->family == AF_INET6 && tsk_striequals(address->ip, "::1"))) {
continue;
}
-
+
// host candidates
ret = tnet_ice_utils_create_sockets(socket_type,
address->ip, &socket_rtp,
self->use_rtcp ? &socket_rtcp : tsk_null);
- if (ret == 0){
+ if (ret == 0) {
const char* foundation_rtp = foundation_default;
tsk_list_lock(self->candidates_local);
- if (socket_rtp){
- if ((candidate = tnet_ice_candidate_create(tnet_ice_cand_type_host, socket_rtp, self->is_ice_jingle, tsk_true, self->is_video, self->ufrag, self->pwd, foundation_default))){
+ if (socket_rtp) {
+ if ((candidate = tnet_ice_candidate_create(tnet_ice_cand_type_host, socket_rtp, self->is_ice_jingle, tsk_true, self->is_video, self->ufrag, self->pwd, foundation_default))) {
foundation_rtp = (const char*)candidate->foundation;
- if (check_best_local_ip && (candidate->socket && (tsk_striequals(candidate->socket->ip, best_local_ip)))){
+ if (check_best_local_ip && (candidate->socket && (tsk_striequals(candidate->socket->ip, best_local_ip)))) {
curr_local_pref = 0xFFFF;
check_best_local_ip = tsk_false;
tnet_ice_candidate_set_local_pref(candidate, curr_local_pref);
tsk_list_push_front_data(self->candidates_local, (void**)&candidate);
}
- else{
+ else {
curr_local_pref = local_pref--;
tnet_ice_candidate_set_local_pref(candidate, curr_local_pref);
tsk_list_push_back_data(self->candidates_local, (void**)&candidate);
}
}
}
- if (socket_rtcp){
- if ((candidate = tnet_ice_candidate_create(tnet_ice_cand_type_host, socket_rtcp, self->is_ice_jingle, tsk_false, self->is_video, self->ufrag, self->pwd, foundation_rtp))){
+ if (socket_rtcp) {
+ if ((candidate = tnet_ice_candidate_create(tnet_ice_cand_type_host, socket_rtcp, self->is_ice_jingle, tsk_false, self->is_video, self->ufrag, self->pwd, foundation_rtp))) {
tnet_ice_candidate_set_local_pref(candidate, curr_local_pref);
tsk_list_push_back_data(self->candidates_local, (void**)&candidate);
}
}
tsk_list_unlock(self->candidates_local);
}
-
+
TSK_OBJECT_SAFE_FREE(socket_rtp);
TSK_OBJECT_SAFE_FREE(socket_rtcp);
-
+
// break if no longer running
- if (!self->is_started){
+ if (!self->is_started) {
break;
}
-
+
TSK_DEBUG_INFO("local ip address = %s", address->ip);
}
-
+
// unlock-list
tsk_list_unlock(self->candidates_local);
-
+
bail:
- if (self->is_started){
- if (ret == 0 && !TSK_LIST_IS_EMPTY(self->candidates_local)){
+ if (self->is_started) {
+ if (ret == 0 && !TSK_LIST_IS_EMPTY(self->candidates_local)) {
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_Success);
}
- else{
+ else {
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_Failure);
}
}
-
+
TSK_OBJECT_SAFE_FREE(addresses);
return ret;
}
@@ -1231,9 +1227,9 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidates_2_GatheringHostCandidatesDo
{
int ret;
tnet_ice_ctx_t* self;
-
+
self = va_arg(*app, tnet_ice_ctx_t *);
-
+
ret = _tnet_ice_ctx_signal_async(self, tnet_ice_event_type_gathering_host_candidates_succeed, "Gathering host candidates succeed");
if (ret == 0) {
if (self->is_stun_enabled && _tnet_ice_ctx_servers_count_by_proto(self, tnet_ice_server_proto_stun) > 0) {
@@ -1251,7 +1247,7 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidates_2_GatheringHostCandidatesDo
}
}
}
-
+
return ret;
}
@@ -1259,7 +1255,7 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidates_2_GatheringHostCandidatesDo
static int _tnet_ice_ctx_fsm_GatheringHostCandidates_2_Terminated_X_Failure(va_list *app)
{
tnet_ice_ctx_t* self;
-
+
self = va_arg(*app, tnet_ice_ctx_t *);
return _tnet_ice_ctx_signal_async(self, tnet_ice_event_type_gathering_host_candidates_failed, "Gathering host candidates failed");
}
@@ -1287,16 +1283,16 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
fd_set set;
tsk_size_t srflx_addr_count_added = 0, srflx_addr_count_skipped = 0, host_addr_count = 0;
long tv_sec, tv_usec; //very important to save these values as timeval could be modified by select() - happens on iOS -
-
+
self = va_arg(*app, tnet_ice_ctx_t *);
-
+
// Get ICE servers to use to gather reflexive candidates
ice_servers = _tnet_ice_ctx_servers_copy(self, tnet_ice_server_proto_stun);
if (!ice_servers || TSK_LIST_IS_EMPTY(ice_servers)) { // not expected to be null or empty because we checked the number of such servers before calling this transition
TSK_DEBUG_WARN("No valid STUN server could be used to gather reflexive candidates");
goto bail;
}
-
+
// set all default values to -1
// = {{ -1 }} will only set the first element
for (i = 0; i < sizeof(fds) / sizeof(fds[0]); ++i) {
@@ -1305,17 +1301,17 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
for (i = 0; i < sizeof(fds_skipped) / sizeof(fds_skipped[0]); ++i) {
fds_skipped[i] = TNET_INVALID_FD;
}
-
+
rc = self->Rc;
tv.tv_sec = tv_sec = 0;
tv.tv_usec = tv_usec = 0;
-
+
// load fds for both rtp and rtcp sockets
tsk_list_foreach(item, self->candidates_local) {
if (!(candidate = item->data)) {
continue;
}
-
+
++host_addr_count;
if ((fds_count < sizeof(fds) / sizeof(fds[0])) && candidate->socket) {
fds[fds_count++] = candidate->socket->fd;
@@ -1324,13 +1320,13 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
}
}
}
-
-
+
+
/* RFC 5389 - 7.2.1. Sending over UDP
A client SHOULD retransmit a STUN request message starting with an
interval of RTO ("Retransmission TimeOut"), doubling after each
retransmission.
-
+
e.g. 0 ms, 500 ms, 1500 ms, 3500 ms, 7500ms, 15500 ms, and 31500 ms
*/
for (i = 0; (i < rc && self->is_started && ((srflx_addr_count_added + srflx_addr_count_skipped) < host_addr_count)); ++i) {
@@ -1362,16 +1358,16 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
#else
tv.tv_usec = tv_usec;
#endif
-
+
TSK_DEBUG_INFO("ICE reflexive candidates gathering ...srv_addr=%s,srv_port=%u,tv_sec=%lu,tv_usec=%lu,rto=%d", ice_server->str_server_addr, ice_server->u_server_port, tv_sec, tv_usec, ice_server->rto);
-
+
FD_ZERO(&set);
for (k = 0; k < fds_count; ++k) {
FD_SET(fds[k], &set);
}
-
+
// sends STUN binding requets
- tsk_list_foreach(item, self->candidates_local){
+ tsk_list_foreach(item, self->candidates_local) {
if (!(candidate = (tnet_ice_candidate_t*)item->data)) {
continue;
}
@@ -1379,7 +1375,7 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
ret = tnet_ice_candidate_send_stun_bind_request(candidate, &ice_server->obj_server_addr, ice_server->str_username, ice_server->str_password);
}
}
-
+
if ((ret = select(fd_max + 1, &set, NULL, NULL, &tv)) < 0) {
TSK_DEBUG_ERROR("select() failed with error code = %d", tnet_geterrno());
goto bail;
@@ -1398,27 +1394,27 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
unsigned int len = 0;
void* data = 0;
const tnet_ice_candidate_t* candidate_curr;
-
+
// Check how many bytes are pending
if ((ret = tnet_ioctlt(fd, FIONREAD, &len)) < 0) {
TSK_DEBUG_ERROR("tnet_ioctlt() failed");
continue;
}
-
+
if (len == 0) {
TSK_DEBUG_INFO("tnet_ioctlt() retured zero bytes");
continue;
}
-
+
// Receive pending data
data = tsk_calloc(len, sizeof(uint8_t));
if ((ret = tnet_sockfd_recv(fd, data, len, 0)) < 0) {
TSK_FREE(data);
-
+
TSK_DEBUG_ERROR("Recving STUN dgrams failed with error code:%d", tnet_geterrno());
continue;
}
-
+
// Parse the incoming response
if ((ret = tnet_stun_pkt_read(data, (tsk_size_t)ret, &response))) {
TSK_FREE(data);
@@ -1435,7 +1431,7 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
tsk_size_t j;
tsk_bool_t already_skipped = tsk_false;
/* refc 5245- 4.1.3. Eliminating Redundant Candidates
-
+
Next, the agent eliminates redundant candidates. A candidate is
redundant if its transport address equals another candidate, and its
base equals the base of that other candidate. Note that two
@@ -1450,7 +1446,7 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
break;
}
}
-
+
if (!already_skipped) {
++srflx_addr_count_skipped;
fds_skipped[j] = fd;
@@ -1488,19 +1484,21 @@ static int _tnet_ice_ctx_fsm_GatheringHostCandidatesDone_2_GatheringReflexiveCan
}
} // tsk_list_foreach (item, ice_servers)...
} // for (i = 0; (i < rc....
-
+
bail:
TSK_DEBUG_INFO("srflx_addr_count_added=%u, srflx_addr_count_skipped=%u", (unsigned)srflx_addr_count_added, (unsigned)srflx_addr_count_skipped);
- if ((srflx_addr_count_added + srflx_addr_count_skipped) > 0) ret = 0; // Hack the returned value if we have at least one success (happens when timeouts)
+ if ((srflx_addr_count_added + srflx_addr_count_skipped) > 0) {
+ ret = 0; // Hack the returned value if we have at least one success (happens when timeouts)
+ }
if (self->is_started) {
if (ret == 0) {
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_Success);
}
- else{
+ else {
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_Failure);
}
}
-
+
tsk_list_foreach(item, self->candidates_local) {
if (!(candidate = (tnet_ice_candidate_t*)item->data)) {
continue;
@@ -1515,9 +1513,9 @@ bail:
static int _tnet_ice_ctx_fsm_GatheringReflexiveCandidates_2_GatheringReflexiveCandidatesDone_X_Success(va_list *app)
{
tnet_ice_ctx_t* self;
-
+
self = va_arg(*app, tnet_ice_ctx_t *);
-
+
if (self->is_started) {
int ret = _tnet_ice_ctx_signal_async(self, tnet_ice_event_type_gathering_reflexive_candidates_succeed, "Gathering reflexive candidates succeed");
if (ret == 0) {
@@ -1560,19 +1558,19 @@ static int _tnet_ice_ctx_fsm_GatheringReflexiveCandidatesDone_2_GatheringRelayCa
tnet_ice_servers_L_t* ice_servers = tsk_null;
tnet_ice_server_t* ice_server;
tnet_ice_candidates_L_t* candidates_local_copy = tsk_null;;
-
+
// Create TURN condwait handle if not already done
if (!self->turn.condwait && !(self->turn.condwait = tsk_condwait_create())) {
TSK_DEBUG_ERROR("Failed to create TURN condwait handle");
ret = -2;
goto bail;
}
-
+
// Copy local ICE candidates
tsk_list_lock(self->candidates_local);
candidates_local_copy = tsk_list_clone(self->candidates_local);
tsk_list_unlock(self->candidates_local);
-
+
// Take reference to the TURN servers
ice_servers = _tnet_ice_ctx_servers_copy(self, tnet_ice_server_proto_turn);
if (!ice_servers || TSK_LIST_IS_EMPTY(ice_servers)) {
@@ -1595,14 +1593,14 @@ next_server:
goto bail;
}
ice_server = (tnet_ice_server_t*)item_server->data;
-
+
// Create TURN sessions for each local host candidate
tsk_list_foreach(item, candidates_local_copy) {
if (!(candidate = item->data)) {
continue;
}
TSK_DEBUG_INFO("Gathering relay candidate: local addr=%s=%d, TURN server=%s:%d", candidate->connection_addr, candidate->port, ice_server->str_server_addr, ice_server->u_server_port);
-
+
// Destroy previvious TURN session (if exist)
TSK_OBJECT_SAFE_FREE(candidate->turn.ss);
if (candidate->type_e == tnet_ice_cand_type_host && candidate->socket) { // do not create TURN session for reflexive candidates
@@ -1648,16 +1646,16 @@ next_server:
++host_addr_count;
}
} // tsk_list_foreach(item, self->candidates_local) {
-
+
rto = self->RTO;
rc = self->Rc;
-
+
for (i = 0; (i < rc && self->is_started && ((relay_addr_count_ok + relay_addr_count_nok) < host_addr_count));) {
if (!self->is_started || !self->is_active) {
TSK_DEBUG_INFO("ICE context stopped/cancelled while gathering TURN candidates");
goto bail;
}
-
+
u_t0 = tsk_time_now();
tsk_condwait_timedwait(self->turn.condwait, rto);
u_t1 = tsk_time_now();
@@ -1666,7 +1664,7 @@ next_server:
rto <<= 1;
++i;
}
-
+
// count the number of TURN sessions with alloc() = ok/nok and ignore ones without response
relay_addr_count_ok = 0;
tsk_list_foreach(item, candidates_local_copy) {
@@ -1685,7 +1683,7 @@ next_server:
}
}
}
-
+
// add/delete TURN candidates
tsk_list_foreach(item, candidates_local_copy) {
if (!(candidate = item->data) || !candidate->turn.ss) {
@@ -1701,7 +1699,7 @@ next_server:
tnet_port_t relay_port;
tnet_ice_candidate_t* new_cand = tsk_null;
struct tnet_socket_s* p_lcl_sock = tsk_null;
-
+
if ((ret = tnet_turn_session_get_relayed_addr(candidate->turn.ss, &relay_addr, &relay_port, &__b_ipv6))) {
goto bail;
}
@@ -1733,12 +1731,12 @@ next_server:
TSK_OBJECT_SAFE_FREE(candidate->turn.ss);
}
}
-
+
// Try next TURN server
if (self->is_started && item_server && relay_addr_count_added == 0) {
goto next_server;
}
-
+
bail:
if (self->is_started) {
if (ret == 0) {
@@ -1778,34 +1776,34 @@ static int _tnet_ice_ctx_fsm_Any_2_Started_X_Cancel(va_list *app)
{
tnet_ice_ctx_t* self;
self = va_arg(*app, tnet_ice_ctx_t *);
-
+
tsk_list_lock(self->candidates_remote);
tsk_list_clear_items(self->candidates_remote);
tsk_list_unlock(self->candidates_remote);
-
+
tsk_list_lock(self->candidates_pairs);
tsk_list_clear_items(self->candidates_pairs);
tsk_list_unlock(self->candidates_pairs);
-
+
TSK_OBJECT_SAFE_FREE(self->turn.ss_nominated_rtp);
TSK_OBJECT_SAFE_FREE(self->turn.ss_nominated_rtcp);
-
+
// Do not clear local candidates because then will be used as fallback if the remote peer is an ICE-lite
// These candidates will be cleared before the next local gathering
// tsk_list_lock(self->candidates_local);
// tsk_list_clear_items(self->candidates_local);
// tsk_list_unlock(self->candidates_local);
-
+
// restore "is_cancelled" until next cancel
// set "is_active" to false to allow ICE re-start
// self->is_cancelled = tsk_false;
// self->is_active = tsk_false;
-
+
// alert user
_tnet_ice_ctx_signal_async(self, tnet_ice_event_type_cancelled, "Cancelled");
-
+
return 0;
-
+
}
// Any -> (GatheringComplet) -> GatheringCompleted
@@ -1814,25 +1812,25 @@ static int _tnet_ice_ctx_fsm_Any_2_GatheringCompleted_X_GatheringComplet(va_list
int ret = 0;
tnet_ice_ctx_t* self;
tsk_bool_t has_remote_candidates;
-
+
self = va_arg(*app, tnet_ice_ctx_t *);
-
+
// alert user
_tnet_ice_ctx_signal_async(self, tnet_ice_event_type_gathering_completed, "Gathering candidates completed");
-
- if (self->is_started){
+
+ if (self->is_started) {
tsk_list_lock(self->candidates_remote);
has_remote_candidates = !TSK_LIST_IS_EMPTY(self->candidates_remote);
tsk_list_unlock(self->candidates_remote);
-
- if (has_remote_candidates){
+
+ if (has_remote_candidates) {
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_ConnCheck);
}
}
- else{
+ else {
return -1;
}
-
+
return ret;
}
@@ -1861,42 +1859,42 @@ static int _tnet_ice_ctx_fsm_GatheringCompleted_2_ConnChecking_X_ConnCheck(va_li
void* recvfrom_buff_ptr = tsk_null;
tsk_size_t recvfrom_buff_size = 0, tries_count = 0, tries_count_min = kIceConnCheckMinTriesMin;
enum tnet_stun_state_e e_state;
-
+
self = va_arg(*app, tnet_ice_ctx_t *);
-
+
self->is_connchecking = tsk_true;
-
+
// "tries_count" and "tries_count_min"
// The connection checks to to the "relay", "prflx", "srflx" and "host" candidates are sent at the same time.
// Because the requests are sent at the same time it's possible to have success check for "relay" (or "srflx") candidates before the "host" candidates.
// "tries_count_min" is the minimum (if success check is not for "host" candidates) tries before giving up.
// The pairs are already sorted ("host"->"srflx"->"prflx", "relay") to make sure to choose the best candidates when there are more than one success conncheck.
-
+
start_conneck:
role_conflict = tsk_false;
restart_conneck = tsk_false;
-
+
tsk_list_lock(self->candidates_pairs);
tsk_list_clear_items(self->candidates_pairs);
tsk_list_unlock(self->candidates_pairs);
-
+
TSK_OBJECT_SAFE_FREE(self->turn.ss_nominated_rtp);
TSK_OBJECT_SAFE_FREE(self->turn.ss_nominated_rtcp);
-
+
if ((ret = _tnet_ice_ctx_build_pairs(self, self->candidates_local, self->candidates_remote, self->candidates_pairs, self->is_controlling, self->tie_breaker, self->is_ice_jingle, self->use_rtcpmux))) {
TSK_DEBUG_ERROR("_tnet_ice_ctx_build_pairs() failed");
goto bail;
}
-
+
#define _FD_ISSET(_fds, _fds_count, _fd, _isset) { uint16_t __i; *_isset = 0; for (__i = 0; __i < _fds_count; ++__i) { if (_fds[__i] == _fd) { *_isset = 1; break; } } }
-
+
// load fds for both rtp and rtcp sockets / create TURN permissions
tsk_list_lock(self->candidates_pairs);
- tsk_list_foreach(item, self->candidates_pairs){
- if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_offer->socket){
+ tsk_list_foreach(item, self->candidates_pairs) {
+ if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_offer->socket) {
continue;
}
-
+
if ((fds_count < sizeof(fds) / sizeof(fds[0])) && pair->candidate_offer->socket) {
if (pair->candidate_offer->turn.ss && (ret = tnet_turn_session_get_state_createperm(pair->candidate_offer->turn.ss, pair->turn_peer_id, &e_state)) == 0) {
if (e_state == tnet_stun_state_none) {
@@ -1924,21 +1922,21 @@ start_conneck:
}
}
tsk_list_unlock(self->candidates_pairs);
-
+
concheck_timeout = self->concheck_timeout;
time_start = time_curr = tsk_time_now();
time_end = (time_start + concheck_timeout);
tries_count_min = fds_turn_count > 0 ? kIceConnCheckMinTriesMax : kIceConnCheckMinTriesMin;
-
+
while (self->is_started && self->is_active && (time_curr < time_end) && !self->have_nominated_symetric) {
tv.tv_sec = 0;
tv.tv_usec = (rto * 1000);
-
+
FD_ZERO(&set);
for (k = 0; k < fds_count; ++k) {
FD_SET(fds[k], &set);
}
-
+
// set new current time here to avoid "continue" skips
// ignore already ellapsed time if new timeout value is defined
time_curr = tsk_time_now();
@@ -1947,7 +1945,7 @@ start_conneck:
time_start = time_curr;
time_end = (time_start + concheck_timeout);
}
-
+
// Send ConnCheck requests
// the pairs are already sorted by priority (from high to low)
if (!self->have_nominated_symetric) {
@@ -1956,21 +1954,22 @@ start_conneck:
continue;
}
switch (pair->state_offer) {
- case tnet_ice_pair_state_failed:
- case tnet_ice_pair_state_succeed:
- continue;
- default: break;
+ case tnet_ice_pair_state_failed:
+ case tnet_ice_pair_state_succeed:
+ continue;
+ default:
+ break;
}
-
+
ret = tnet_ice_pair_send_conncheck((tnet_ice_pair_t *)pair);
}
}
-
+
if (fds_count == 0) {
tsk_thread_sleep(10);
goto check_nomination;
}
-
+
if ((ret = select(fd_max + 1, &set, NULL, NULL, &tv)) < 0) {
TNET_PRINT_LAST_ERROR("select() failed");
goto bail;
@@ -1986,30 +1985,30 @@ start_conneck:
tnet_fd_t fd = fds[k];
unsigned int len = 0;
tsk_size_t read = 0;
-
+
if (!FD_ISSET(fd, &set)) {
continue;
}
-
+
// Check how many bytes are pending
if ((ret = tnet_ioctlt(fd, FIONREAD, &len)) < 0) {
continue;
}
-
- if (len == 0){
+
+ if (len == 0) {
// TSK_DEBUG_INFO("tnet_ioctlt() returent zero bytes");
continue;
}
-
+
// Receive pending data
- if (recvfrom_buff_size < len){
- if (!(recvfrom_buff_ptr = tsk_realloc(recvfrom_buff_ptr, len))){
+ if (recvfrom_buff_size < len) {
+ if (!(recvfrom_buff_ptr = tsk_realloc(recvfrom_buff_ptr, len))) {
recvfrom_buff_size = 0;
goto bail;
}
recvfrom_buff_size = len;
}
-
+
// receive all messages
while (self->is_started && self->is_active && read < len && ret == 0) {
if ((ret = tnet_sockfd_recvfrom(fd, recvfrom_buff_ptr, recvfrom_buff_size, 0, (struct sockaddr *)&remote_addr)) < 0) {
@@ -2024,13 +2023,13 @@ start_conneck:
len = 0;
continue;
}
-
+
TNET_PRINT_LAST_ERROR("Receiving STUN dgrams failed with errno=%d", err);
goto bail;
}
-
+
read += ret;
-
+
// recv() STUN message (request / response)
ret = tnet_ice_ctx_recv_stun_message(self, recvfrom_buff_ptr, (tsk_size_t)ret, fd, &remote_addr, &role_conflict);
if (ret == 0 && role_conflict) {
@@ -2041,13 +2040,13 @@ start_conneck:
}
}
}
-
- check_nomination:
+
+check_nomination:
// check whether we need to re-start connection checking
if (restart_conneck) {
goto start_conneck;
}
-
+
check_rtcp = (self->use_rtcp && !self->use_rtcpmux);
if (!self->have_nominated_offer) {
self->have_nominated_offer = tnet_ice_pairs_have_nominated_offer(self->candidates_pairs, check_rtcp);
@@ -2060,11 +2059,11 @@ start_conneck:
self->have_nominated_symetric &= (got_hosts || ((tries_count++) >= tries_count_min));
}
} // while (self->is_started...
-
+
// "ret" could be "<>0" if last function used was "select()", "recvfrom()", "ioctlt()"...this is why we set the value to #0.
// if there was an error then, we'll jump to "bail:" and next code is skipped
ret = 0;
-
+
bail:
// move to the next state depending on the conncheck result
if (self->is_started) {
@@ -2081,11 +2080,11 @@ bail:
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_Failure);
}
}
-
+
TSK_FREE(recvfrom_buff_ptr);
-
+
self->is_connchecking = tsk_false;
-
+
return ret;
}
@@ -2099,19 +2098,19 @@ static int _tnet_ice_ctx_fsm_ConnChecking_2_ConnCheckingCompleted_X_Success(va_l
const tnet_ice_candidate_t *candidate;
tsk_list_t* sessions = tsk_list_create(); // for lock-free TURN sessions destroying
int ret;
-
+
// When destroying TURN sessions the transport is locked by shutdown()
// This function locks "self->candidates_pairs"
// TURN callback locks "self->candidates_pairs"
// TURN callback locks the transport
// => We must not lock the candidates when destroying the TURN session
// Test with WES8 if you want to reproduce the issue
-
+
TSK_OBJECT_SAFE_FREE(self->turn.ss_nominated_rtp);
TSK_OBJECT_SAFE_FREE(self->turn.ss_nominated_rtcp);
-
+
tsk_list_lock(self->candidates_pairs);
-
+
// take a reference to the negotiated TURN sessions
ret = tnet_ice_pairs_get_nominated_symetric_pairs(self->candidates_pairs, TNET_ICE_CANDIDATE_COMPID_RTP, &pair_offer, &pair_answer_src, &pair_answer_dest);
if (ret == 0) {
@@ -2123,8 +2122,10 @@ static int _tnet_ice_ctx_fsm_ConnChecking_2_ConnCheckingCompleted_X_Success(va_l
TSK_DEBUG_INFO("ICE: nominated symetric RTP pairs: offer:%llu, answer-src:%llu, answser-dest:%llu",
pair_offer ? pair_offer->id : 0, pair_answer_src ? pair_answer_src->id : 0, pair_answer_dest ? pair_answer_dest->id : 0);
}
- if (ret == 0 && pair_offer) { ((tnet_ice_pair_t *)pair_offer)->is_nominated = tsk_true; } // "is_nominated" is used do decide whether to include "USE-CANDIDATE" attribute when aggressive mode is disabled
-
+ if (ret == 0 && pair_offer) {
+ ((tnet_ice_pair_t *)pair_offer)->is_nominated = tsk_true; // "is_nominated" is used do decide whether to include "USE-CANDIDATE" attribute when aggressive mode is disabled
+ }
+
ret = tnet_ice_pairs_get_nominated_symetric_pairs(self->candidates_pairs, TNET_ICE_CANDIDATE_COMPID_RTCP, &pair_offer, &pair_answer_src, &pair_answer_dest);
if (ret == 0) {
if (pair_offer && pair_offer->candidate_offer && pair_offer->candidate_offer->type_e == tnet_ice_cand_type_relay && pair_offer->candidate_offer->turn.ss) {
@@ -2136,8 +2137,10 @@ static int _tnet_ice_ctx_fsm_ConnChecking_2_ConnCheckingCompleted_X_Success(va_l
self->use_rtcp ? 1 : 0, self->use_rtcpmux ? 1 : 0,
pair_offer ? pair_offer->id : 0, pair_answer_src ? pair_answer_src->id : 0, pair_answer_dest ? pair_answer_dest->id : 0);
}
- if (ret == 0 && pair_offer) { ((tnet_ice_pair_t *)pair_offer)->is_nominated = tsk_true; } // "is_nominated" is used do decide whether to include "USE-CANDIDATE" attribute when aggressive mode is disabled
-
+ if (ret == 0 && pair_offer) {
+ ((tnet_ice_pair_t *)pair_offer)->is_nominated = tsk_true; // "is_nominated" is used do decide whether to include "USE-CANDIDATE" attribute when aggressive mode is disabled
+ }
+
// collect all useless TURN sessions (pairs)
tsk_list_foreach(item, self->candidates_pairs) {
if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_offer->turn.ss) {
@@ -2148,9 +2151,9 @@ static int _tnet_ice_ctx_fsm_ConnChecking_2_ConnCheckingCompleted_X_Success(va_l
TSK_OBJECT_SAFE_FREE(pair->candidate_offer->turn.ss);
}
}
-
+
tsk_list_unlock(self->candidates_pairs);
-
+
// collect all useless TURN sessions (local candidates)
tsk_list_lock(self->candidates_local);
tsk_list_foreach(item, self->candidates_local) {
@@ -2163,7 +2166,7 @@ static int _tnet_ice_ctx_fsm_ConnChecking_2_ConnCheckingCompleted_X_Success(va_l
}
}
tsk_list_unlock(self->candidates_local);
-
+
// collect all useless TURN sessions (remote candidates)
tsk_list_lock(self->candidates_remote);
tsk_list_foreach(item, self->candidates_remote) {
@@ -2176,10 +2179,10 @@ static int _tnet_ice_ctx_fsm_ConnChecking_2_ConnCheckingCompleted_X_Success(va_l
}
}
tsk_list_unlock(self->candidates_remote);
-
+
// lock-free destruction
TSK_OBJECT_SAFE_FREE(sessions);
-
+
return _tnet_ice_ctx_signal_async(self, tnet_ice_event_type_conncheck_succeed, "ConnCheck succeed");
}
@@ -2203,15 +2206,15 @@ static int _tnet_ice_ctx_fsm_Any_2_Terminated_X_AnyNotStarted(va_list *app)
static int _tnet_ice_ctx_fsm_OnTerminated(tnet_ice_ctx_t* self)
{
TSK_DEBUG_INFO("=== ICE CTX SM Terminated ===");
-
- if (!self){
+
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter.");
return -1;
}
-
+
// still started but no longer active
self->is_active = tsk_false;
-
+
return 0;
}
@@ -2227,10 +2230,10 @@ static int _tnet_ice_ctx_restart(tnet_ice_ctx_t* self)
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
ret = tsk_fsm_set_current_state(self->fsm, _fsm_state_Started);
ret = _tnet_ice_ctx_fsm_act(self, _fsm_action_GatherHostCandidates);
-
+
self->is_active = (ret == 0);
return ret;
}
@@ -2243,9 +2246,9 @@ static int _tnet_ice_ctx_recv_stun_message_for_pair(tnet_ice_ctx_t* self, const
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
*role_conflict = tsk_false;
-
+
if (!TNET_STUN_BUFF_IS_STUN2(((uint8_t*)data), size)) {
if (self->rtp_callback) {
return self->rtp_callback(self->rtp_callback_data, data, size, local_fd, remote_addr);
@@ -2253,12 +2256,12 @@ static int _tnet_ice_ctx_recv_stun_message_for_pair(tnet_ice_ctx_t* self, const
TSK_DEBUG_INFO("Not STUN message");
return 0;
}
-
+
if (!self->is_active) {
TSK_DEBUG_INFO("ICE context not active yet");
return 0;
}
-
+
if ((ret = tnet_stun_pkt_read(data, size, &message)) == 0 && message) {
if (message->e_type == tnet_stun_pkt_type_binding_request) {
tsk_bool_t is_local_conncheck_started;
@@ -2278,7 +2281,7 @@ static int _tnet_ice_ctx_recv_stun_message_for_pair(tnet_ice_ctx_t* self, const
if (!pair && is_local_conncheck_started) {
pair = tnet_ice_pairs_find_by_fd_and_addr(self->candidates_pairs, local_fd, remote_addr);
}
- if (!pair && !self->have_nominated_symetric && is_local_conncheck_started){ // pair not found and we're still negotiating
+ if (!pair && !self->have_nominated_symetric && is_local_conncheck_started) { // pair not found and we're still negotiating
// rfc 5245 - 7.1.3.2.1. Discovering Peer Reflexive Candidates
tnet_ice_pair_t* pair_peer = tnet_ice_pair_prflx_create(self->candidates_pairs, local_fd, remote_addr);
if (pair_peer) {
@@ -2292,12 +2295,12 @@ static int _tnet_ice_ctx_recv_stun_message_for_pair(tnet_ice_ctx_t* self, const
char* resp_phrase = tsk_null;
// authenticate the request
tnet_ice_pair_auth_conncheck(pair, message, data, size, &resp_code, &resp_phrase);
- if (resp_code > 0 && resp_phrase){
- if (resp_code >= 200 && resp_code <= 299){
+ if (resp_code > 0 && resp_phrase) {
+ if (resp_code >= 200 && resp_code <= 299) {
// Before sending the success response check that there are no role conflict
- if (self->is_controlling){ // I'm ICE-CONTROLLING
+ if (self->is_controlling) { // I'm ICE-CONTROLLING
const tnet_stun_attr_vdata_t* stun_att_ice_controlling;
- if ((ret = tnet_stun_pkt_attr_find_first(message, tnet_stun_attr_type_ice_controlling, (const tnet_stun_attr_t**)&stun_att_ice_controlling)) == 0 && stun_att_ice_controlling){
+ if ((ret = tnet_stun_pkt_attr_find_first(message, tnet_stun_attr_type_ice_controlling, (const tnet_stun_attr_t**)&stun_att_ice_controlling)) == 0 && stun_att_ice_controlling) {
TSK_DEBUG_WARN("Role conflicts (SEND)");
if (self->tie_breaker >= *((uint64_t*)stun_att_ice_controlling->p_data_ptr)) {
resp_code = kStunErrCodeIceConflict;
@@ -2363,13 +2366,13 @@ static int _tnet_ice_ctx_recv_stun_message_for_pair(tnet_ice_ctx_t* self, const
}
}
TSK_OBJECT_SAFE_FREE(message);
-
+
return ret;
}
static int _tnet_ice_ctx_send_turn_raw(struct tnet_ice_ctx_s* self, struct tnet_turn_session_s* turn_ss, tnet_turn_peer_id_t turn_peer_id, const void* data, tsk_size_t size)
{
- if (!self || !turn_ss || !data || !size){
+ if (!self || !turn_ss || !data || !size) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -2386,21 +2389,21 @@ static int _tnet_ice_ctx_build_pairs(struct tnet_ice_ctx_s* self, tnet_ice_candi
tnet_ice_pair_t *pair;
enum tnet_turn_transport_e e_req_transport;
tnet_family_t addr_family_local, addr_family_remote;
-
+
if (!self || TSK_LIST_IS_EMPTY(local_candidates) || TSK_LIST_IS_EMPTY(remote_candidates) || !result_pairs) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
self->is_building_pairs = tsk_true;
TSK_DEBUG_INFO("ICE: begin building pairs(is_rtcpmuxed=%d)", is_rtcpmuxed);
-
+
tsk_list_clear_items(result_pairs);
-
+
tsk_list_lock(local_candidates);
tsk_list_lock(remote_candidates);
tsk_list_lock(result_pairs);
-
+
tsk_list_foreach(item_local, local_candidates) {
if (!(cand_local = item_local->data)) {
continue;
@@ -2413,7 +2416,7 @@ static int _tnet_ice_ctx_build_pairs(struct tnet_ice_ctx_s* self, tnet_ice_candi
continue;
}
#endif
-
+
tsk_list_foreach(item_remote, remote_candidates) {
if (!(cand_remote = item_remote->data)) {
continue;
@@ -2423,9 +2426,9 @@ static int _tnet_ice_ctx_build_pairs(struct tnet_ice_ctx_s* self, tnet_ice_candi
TSK_DEBUG_INFO("Skipping remote ICE candidate with port = 0");
continue;
}
-
+
// CompIds(1=RTP, 2=RTCP) must match
- if ((cand_remote->comp_id != cand_local->comp_id)){
+ if ((cand_remote->comp_id != cand_local->comp_id)) {
continue;
}
// IP versions must match. Cannot use IPv4 socket to send/recv to IPv6 address.
@@ -2453,18 +2456,18 @@ static int _tnet_ice_ctx_build_pairs(struct tnet_ice_ctx_s* self, tnet_ice_candi
continue;
}
}
-
+
if ((pair = tnet_ice_pair_create(cand_local, cand_remote, is_controlling, tie_breaker, is_ice_jingle))) {
TSK_DEBUG_INFO("ICE Pair(%llu, %llu): [%s %u %u %s %d] -> [%s %u %u %s %d]",
pair->id,
pair->priority,
-
+
cand_local->foundation,
cand_local->priority,
cand_local->comp_id,
cand_local->connection_addr,
cand_local->port,
-
+
cand_remote->foundation,
cand_remote->priority,
cand_remote->comp_id,
@@ -2479,31 +2482,31 @@ static int _tnet_ice_ctx_build_pairs(struct tnet_ice_ctx_s* self, tnet_ice_candi
if (!(pair = item_local->data)) {
continue;
}
-
+
TSK_DEBUG_INFO("ICE Pair(%llu, %llu): [%s %u %s %d] -> [%s %u %s %d]",
pair->id,
pair->priority,
-
+
pair->candidate_offer->foundation,
pair->candidate_offer->comp_id,
pair->candidate_offer->connection_addr,
pair->candidate_offer->port,
-
+
pair->candidate_answer->foundation,
pair->candidate_answer->comp_id,
pair->candidate_answer->connection_addr,
pair->candidate_answer->port);
}
#endif
-
+
tsk_list_unlock(local_candidates);
tsk_list_unlock(remote_candidates);
tsk_list_unlock(result_pairs);
-
+
self->is_building_pairs = tsk_false;
tsk_condwait_broadcast(self->condwait_pairs);
TSK_DEBUG_INFO("ICE: end building pairs");
-
+
return 0;
}
@@ -2514,32 +2517,32 @@ static int _tnet_ice_ctx_fsm_act(tnet_ice_ctx_t* self, tsk_fsm_action_id action_
tnet_ice_event_t* e = tsk_null;
static const char* phrase = "$action$";
int ret = 0;
-
- if (!self || !self->fsm){
+
+ if (!self || !self->fsm) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
- if (!(action = tnet_ice_action_create(action_id))){
+ if (!(action = tnet_ice_action_create(action_id))) {
TSK_DEBUG_ERROR("Failed to create action");
return -2;
}
-
+
if (self->is_sync_mode) {
ret = tsk_fsm_act(self->fsm, action->id, self, action, self, action);
}
else {
- if ((e = tnet_ice_event_create(self, tnet_ice_event_type_action, phrase, self->userdata))){
+ if ((e = tnet_ice_event_create(self, tnet_ice_event_type_action, phrase, self->userdata))) {
tnet_ice_event_set_action(e, action);
TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(self), e);
goto bail;
}
- else{
+ else {
TSK_DEBUG_ERROR("Failed to create ICE event");
ret = -2;
goto bail;
}
}
-
+
bail:
TSK_OBJECT_SAFE_FREE(e);
TSK_OBJECT_SAFE_FREE(action);
@@ -2549,21 +2552,21 @@ bail:
static int _tnet_ice_ctx_signal_async(tnet_ice_ctx_t* self, tnet_ice_event_type_t type, const char* phrase)
{
tnet_ice_event_t* e;
- if (!self){
+ if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
if (self->is_silent_mode && type != tnet_ice_event_type_action) { // silent mode ON and not action to move the FSM
TSK_DEBUG_INFO("ICE silent mode ON...to not notify '%d:%s'", type, phrase);
return 0;
}
-
- if ((e = tnet_ice_event_create(self, type, phrase, self->userdata))){
+
+ if ((e = tnet_ice_event_create(self, type, phrase, self->userdata))) {
TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(self), e);
return 0;
}
- else{
+ else {
TSK_DEBUG_ERROR("Failed to create ICE event");
return -2;
}
@@ -2574,114 +2577,110 @@ static int _tnet_ice_ctx_turn_callback(const struct tnet_turn_session_event_xs *
tnet_ice_ctx_t *ctx = tsk_object_ref(TSK_OBJECT(e->pc_usr_data));
struct tnet_turn_session_s* session = tsk_object_ref(TSK_OBJECT(e->pc_session));
int ret = 0;
-
+
if (!ctx) {
// the ICE context is being destroyed but TURN session not freed yet
goto bail;
}
-
+
switch (e->e_type) {
- case tnet_turn_session_event_type_alloc_ok:
- case tnet_turn_session_event_type_refresh_ok:
- case tnet_turn_session_event_type_chanbind_ok:
- case tnet_turn_session_event_type_connect_ok:
- default:
- {
- break;
- }
-
- case tnet_turn_session_event_type_alloc_nok:
- case tnet_turn_session_event_type_refresh_nok:
- case tnet_turn_session_event_type_perm_nok:
- case tnet_turn_session_event_type_chanbind_nok:
- case tnet_turn_session_event_type_connect_nok:
- {
- // Do not raise error event if no nominated candidate because
- // TURN error could be raised by the session when we're in "conncheck" state and this is a normal case.
- if (ctx->is_active && ctx->is_started && ctx->turn.ss_nominated_rtp && ctx->turn.peer_id_rtp == e->u_peer_id) {
- TSK_DEBUG_ERROR("TURN connection broken (peer-id=%ld)", e->u_peer_id);
- if ((ret = _tnet_ice_ctx_signal_async(ctx, tnet_ice_event_type_turn_connection_broken, "TURN connection is broken"))) {
- goto bail;
- }
+ case tnet_turn_session_event_type_alloc_ok:
+ case tnet_turn_session_event_type_refresh_ok:
+ case tnet_turn_session_event_type_chanbind_ok:
+ case tnet_turn_session_event_type_connect_ok:
+ default: {
+ break;
+ }
+
+ case tnet_turn_session_event_type_alloc_nok:
+ case tnet_turn_session_event_type_refresh_nok:
+ case tnet_turn_session_event_type_perm_nok:
+ case tnet_turn_session_event_type_chanbind_nok:
+ case tnet_turn_session_event_type_connect_nok: {
+ // Do not raise error event if no nominated candidate because
+ // TURN error could be raised by the session when we're in "conncheck" state and this is a normal case.
+ if (ctx->is_active && ctx->is_started && ctx->turn.ss_nominated_rtp && ctx->turn.peer_id_rtp == e->u_peer_id) {
+ TSK_DEBUG_ERROR("TURN connection broken (peer-id=%ld)", e->u_peer_id);
+ if ((ret = _tnet_ice_ctx_signal_async(ctx, tnet_ice_event_type_turn_connection_broken, "TURN connection is broken"))) {
+ goto bail;
}
- break;
}
-
- case tnet_turn_session_event_type_perm_ok:
- {
- enum tnet_turn_transport_e e_req_transport;
- if ((ret = tnet_turn_session_get_req_transport(session, &e_req_transport))) {
+ break;
+ }
+
+ case tnet_turn_session_event_type_perm_ok: {
+ enum tnet_turn_transport_e e_req_transport;
+ if ((ret = tnet_turn_session_get_req_transport(session, &e_req_transport))) {
+ goto bail;
+ }
+
+ if (e_req_transport == tnet_turn_transport_tcp) {
+ // TCP-Connect: rfc6062 - 4.3. Initiating a Connection
+ if ((ret = tnet_turn_session_connect(session, e->u_peer_id))) {
goto bail;
}
-
- if (e_req_transport == tnet_turn_transport_tcp) {
- // TCP-Connect: rfc6062 - 4.3. Initiating a Connection
- if ((ret = tnet_turn_session_connect(session, e->u_peer_id))) {
- goto bail;
- }
+ }
+ else {
+ // Bind a channel (not required). If succeed, will be used to save bandwidth usage.
+ // TODO: should be done only if first "get_state(chanbind)==none". Not an issue, if it already exists then, will be refreshed.
+ if ((ret = tnet_turn_session_chanbind(session, e->u_peer_id))) {
+ goto bail;
}
- else {
- // Bind a channel (not required). If succeed, will be used to save bandwidth usage.
- // TODO: should be done only if first "get_state(chanbind)==none". Not an issue, if it already exists then, will be refreshed.
- if ((ret = tnet_turn_session_chanbind(session, e->u_peer_id))) {
- goto bail;
+ }
+ break;
+ }
+
+ case tnet_turn_session_event_type_recv_data: {
+ tsk_bool_t role_conflict;
+ tnet_ice_pair_t* pair = tsk_null;
+ if (e->u_peer_id != kTurnPeerIdInvalid) {
+ const tsk_list_item_t *item;
+ tsk_list_lock(ctx->candidates_pairs);
+ tsk_list_foreach(item, ctx->candidates_pairs) {
+ if (((const tnet_ice_pair_t*)item->data)->turn_peer_id == e->u_peer_id) {
+ pair = tsk_object_ref((void*)item->data);
+ break;
}
}
- break;
+ tsk_list_unlock(ctx->candidates_pairs);
}
-
- case tnet_turn_session_event_type_recv_data:
- {
- tsk_bool_t role_conflict;
- tnet_ice_pair_t* pair = tsk_null;
- if (e->u_peer_id != kTurnPeerIdInvalid) {
- const tsk_list_item_t *item;
- tsk_list_lock(ctx->candidates_pairs);
- tsk_list_foreach(item, ctx->candidates_pairs) {
- if (((const tnet_ice_pair_t*)item->data)->turn_peer_id == e->u_peer_id) {
- pair = tsk_object_ref((void*)item->data);
- break;
- }
- }
- tsk_list_unlock(ctx->candidates_pairs);
- }
-
- ret = _tnet_ice_ctx_recv_stun_message_for_pair(
- ctx,
- pair,
- e->data.pc_data_ptr, e->data.u_data_size,
- e->pc_enet ? e->pc_enet->local_fd : TNET_INVALID_FD,
- e->pc_enet ? &e->pc_enet->remote_addr : tsk_null,
- &role_conflict);
- TSK_OBJECT_SAFE_FREE(pair);
- if (ret) {
+
+ ret = _tnet_ice_ctx_recv_stun_message_for_pair(
+ ctx,
+ pair,
+ e->data.pc_data_ptr, e->data.u_data_size,
+ e->pc_enet ? e->pc_enet->local_fd : TNET_INVALID_FD,
+ e->pc_enet ? &e->pc_enet->remote_addr : tsk_null,
+ &role_conflict);
+ TSK_OBJECT_SAFE_FREE(pair);
+ if (ret) {
+ goto bail;
+ }
+
+ // rebuild candidates if role conflict
+ if (role_conflict) {
+ tsk_list_lock(ctx->candidates_pairs);
+ tsk_list_clear_items(ctx->candidates_pairs);
+ tsk_list_unlock(ctx->candidates_pairs);
+
+ TSK_OBJECT_SAFE_FREE(ctx->turn.ss_nominated_rtp);
+ TSK_OBJECT_SAFE_FREE(ctx->turn.ss_nominated_rtcp);
+
+ if ((ret = _tnet_ice_ctx_build_pairs(ctx, ctx->candidates_local, ctx->candidates_remote, ctx->candidates_pairs, ctx->is_controlling, ctx->tie_breaker, ctx->is_ice_jingle, ctx->use_rtcpmux))) {
+ TSK_DEBUG_ERROR("_tnet_ice_ctx_build_pairs() failed");
goto bail;
}
-
- // rebuild candidates if role conflict
- if (role_conflict) {
- tsk_list_lock(ctx->candidates_pairs);
- tsk_list_clear_items(ctx->candidates_pairs);
- tsk_list_unlock(ctx->candidates_pairs);
-
- TSK_OBJECT_SAFE_FREE(ctx->turn.ss_nominated_rtp);
- TSK_OBJECT_SAFE_FREE(ctx->turn.ss_nominated_rtcp);
-
- if ((ret = _tnet_ice_ctx_build_pairs(ctx, ctx->candidates_local, ctx->candidates_remote, ctx->candidates_pairs, ctx->is_controlling, ctx->tie_breaker, ctx->is_ice_jingle, ctx->use_rtcpmux))) {
- TSK_DEBUG_ERROR("_tnet_ice_ctx_build_pairs() failed");
- goto bail;
- }
- }
-
- break;
}
+
+ break;
}
-
+ }
+
// alert() waiting threads
if ((ret = tsk_condwait_broadcast(ctx->turn.condwait))) {
goto bail;
}
-
+
bail:
tsk_object_unref(ctx);
tsk_object_unref(session);
@@ -2694,42 +2693,40 @@ static void* TSK_STDCALL _tnet_ice_ctx_run(void* self)
tsk_list_item_t *curr;
tnet_ice_ctx_t *ctx = (tnet_ice_ctx_t *)(self);
tnet_ice_event_t *e;
-
+
TSK_DEBUG_INFO("ICE CTX::run -- START");
-
+
TSK_RUNNABLE_RUN_BEGIN(ctx);
-
+
// must because "ctx->callback(e);" could call a function trying to free "ctx"
// do not move before "TSK_RUNNABLE_RUN_BEGIN(ctx)", otherwise it'll be required to stop the "runnable" to have "ctx->refCount==0"
ctx = tsk_object_ref(ctx);
-
+
if (ctx->is_started && (curr = TSK_RUNNABLE_POP_FIRST(ctx))) {
e = (tnet_ice_event_t*)curr->data;
switch (e->type) {
- case tnet_ice_event_type_action:
- {
- if (e->action) {
- tsk_fsm_act(ctx->fsm, e->action->id, ctx, e->action, ctx, e->action);
- }
- break;
+ case tnet_ice_event_type_action: {
+ if (e->action) {
+ tsk_fsm_act(ctx->fsm, e->action->id, ctx, e->action, ctx, e->action);
}
- default:
- {
- if (ctx->callback){
- ctx->callback(e);
- }
- break;
+ break;
+ }
+ default: {
+ if (ctx->callback) {
+ ctx->callback(e);
}
+ break;
+ }
}
tsk_object_unref(curr);
}
-
+
if (!(ctx = tsk_object_unref(ctx))) {
goto exit;
}
-
+
TSK_RUNNABLE_RUN_END(ctx);
-
+
exit:
if (ctx) {
tsk_list_clear_items(ctx->candidates_local);
@@ -2738,9 +2735,9 @@ exit:
tsk_list_clear_items(ctx->candidates_pairs);
tsk_list_unlock(ctx->candidates_pairs);
}
-
+
TSK_DEBUG_INFO("ICE CTX::run -- STOP");
-
+
return 0;
}
@@ -2768,7 +2765,7 @@ static int _tnet_ice_ctx_server_add(struct tnet_ice_ctx_s* self, enum tnet_ice_s
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
// TURN requires credentials
if ((e_proto & tnet_ice_server_proto_turn) == tnet_ice_server_proto_turn && (tsk_strnullORempty(str_username) || tsk_strnullORempty(str_password))) {
/* rfc5766 - 4. General Behavior
@@ -2791,7 +2788,7 @@ static int _tnet_ice_ctx_server_add(struct tnet_ice_ctx_s* self, enum tnet_ice_s
}
tsk_list_push_back_data(self->servers, (void**)&ice_server);
TSK_OBJECT_SAFE_FREE(ice_server);
-
+
ret = 0;
bail:
tsk_list_unlock(self->servers);
diff --git a/tinyNET/src/ice/tnet_ice_ctx.h b/tinyNET/src/ice/tnet_ice_ctx.h
index 015fdcf..8be8164 100755
--- a/tinyNET/src/ice/tnet_ice_ctx.h
+++ b/tinyNET/src/ice/tnet_ice_ctx.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2012-2015 Doubango Telecom <http://www.doubango.org>.
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -46,21 +46,21 @@ TINYNET_API struct tnet_ice_ctx_s* tnet_ice_ctx_create(tsk_bool_t is_ice_jingle,
TINYNET_API int tnet_ice_ctx_set_userdata(struct tnet_ice_ctx_s* self, const void* userdata);
//@deprecated: Use "tnet_ice_ctx_add_server()"
TNET_DEPRECATED(TINYNET_API int tnet_ice_ctx_set_stun(
- struct tnet_ice_ctx_s* self,
- const char* server_addr,
- uint16_t server_port,
- const char* software,
- const char* username,
- const char* password));
+ struct tnet_ice_ctx_s* self,
+ const char* server_addr,
+ uint16_t server_port,
+ const char* software,
+ const char* username,
+ const char* password));
TINYNET_API int tnet_ice_ctx_add_server(
- struct tnet_ice_ctx_s* self,
- const char* transport_proto, // "udp", "tcp", "tls", "ws", "wss"...
- const char* server_addr,
- uint16_t server_port,
- tsk_bool_t use_turn,
- tsk_bool_t use_stun,
- const char* username,
- const char* password);
+ struct tnet_ice_ctx_s* self,
+ const char* transport_proto, // "udp", "tcp", "tls", "ws", "wss"...
+ const char* server_addr,
+ uint16_t server_port,
+ tsk_bool_t use_turn,
+ tsk_bool_t use_stun,
+ const char* username,
+ const char* password);
#define tnet_ice_ctx_add_server_turn(self, transport_proto, server_addr, server_port, username, password) \
tnet_ice_ctx_add_server((self), (transport_proto), (server_addr), (server_port), tsk_true/*use_turn*/, tsk_false/*use_stun*/, (username), (password))
#define tnet_ice_ctx_add_server_stun(self, transport_proto, server_addr, server_port, username, password) \
@@ -90,9 +90,9 @@ TINYNET_API tsk_bool_t tnet_ice_ctx_is_can_recv(const struct tnet_ice_ctx_s* sel
TINYNET_API tsk_bool_t tnet_ice_ctx_use_ipv6(const struct tnet_ice_ctx_s* self);
TINYNET_API tsk_bool_t tnet_ice_ctx_use_rtcp(const struct tnet_ice_ctx_s* self);
TINYNET_API int tnet_ice_ctx_get_nominated_symetric_candidates(const struct tnet_ice_ctx_s* self, uint32_t comp_id,
- const struct tnet_ice_candidate_s** candidate_offer,
- const struct tnet_ice_candidate_s** candidate_answer_src,
- const struct tnet_ice_candidate_s** candidate_answer_dest);
+ const struct tnet_ice_candidate_s** candidate_offer,
+ const struct tnet_ice_candidate_s** candidate_answer_src,
+ const struct tnet_ice_candidate_s** candidate_answer_dest);
TINYNET_API int tnet_ice_ctx_recv_stun_message(struct tnet_ice_ctx_s* self, const void* data, tsk_size_t size, tnet_fd_t local_fd, const struct sockaddr_storage* remote_addr, tsk_bool_t *role_conflict);
TINYNET_API int tnet_ice_ctx_send_turn_rtp(struct tnet_ice_ctx_s* self, const void* data, tsk_size_t size);
TINYNET_API int tnet_ice_ctx_send_turn_rtcp(struct tnet_ice_ctx_s* self, const void* data, tsk_size_t size);
diff --git a/tinyNET/src/ice/tnet_ice_event.c b/tinyNET/src/ice/tnet_ice_event.c
index 480202f..1826c3b 100755
--- a/tinyNET/src/ice/tnet_ice_event.c
+++ b/tinyNET/src/ice/tnet_ice_event.c
@@ -27,24 +27,23 @@
static tsk_object_t* tnet_ice_event_ctor(tsk_object_t * self, va_list * app)
{
tnet_ice_event_t *e = self;
- if(e){
-
+ if(e) {
+
}
return self;
}
static tsk_object_t* tnet_ice_event_dtor(tsk_object_t * self)
{
tnet_ice_event_t *e = self;
- if(e){
+ if(e) {
TSK_SAFE_FREE(e->phrase);
TSK_OBJECT_SAFE_FREE(e->action);
e->ctx = tsk_null; // not the owner (const)
}
-
+
return self;
}
-static const tsk_object_def_t tnet_ice_event_def_s =
-{
+static const tsk_object_def_t tnet_ice_event_def_s = {
sizeof(tnet_ice_event_t),
tnet_ice_event_ctor,
tnet_ice_event_dtor,
@@ -56,29 +55,29 @@ const tsk_object_def_t *tnet_ice_event_def_t = &tnet_ice_event_def_s;
tnet_ice_event_t* tnet_ice_event_create(const struct tnet_ice_ctx_s* ctx, tnet_ice_event_type_t type, const char* phrase, const void* userdata)
{
tnet_ice_event_t* e;
-
- if((e = tsk_object_new(tnet_ice_event_def_t))){
+
+ if((e = tsk_object_new(tnet_ice_event_def_t))) {
e->ctx = ctx;
e->type = type;
e->phrase = tsk_strdup(phrase);
e->userdata = userdata;
}
- else{
+ else {
TSK_DEBUG_ERROR("Failed to create ICE event");
}
-
+
return e;
}
int tnet_ice_event_set_action(tnet_ice_event_t* self, struct tnet_ice_action_s* action)
{
- if(!self){
+ if(!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
self->type = tnet_ice_event_type_action;
TSK_OBJECT_SAFE_FREE(self->action);
- if(action){
+ if(action) {
self->action = tsk_object_ref(action);
}
return 0;
diff --git a/tinyNET/src/ice/tnet_ice_event.h b/tinyNET/src/ice/tnet_ice_event.h
index 8f2f72e..404f765 100755
--- a/tinyNET/src/ice/tnet_ice_event.h
+++ b/tinyNET/src/ice/tnet_ice_event.h
@@ -8,12 +8,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -28,40 +28,38 @@
TNET_BEGIN_DECLS
-typedef enum tnet_ice_event_type_e
-{
- // Public events
- tnet_ice_event_type_started,
- tnet_ice_event_type_start_failed,
- tnet_ice_event_type_stopped,
- tnet_ice_event_type_stop_failed,
- tnet_ice_event_type_gathering_host_candidates_failed,
- tnet_ice_event_type_gathering_host_candidates_succeed,
- tnet_ice_event_type_gathering_reflexive_candidates_failed,
- tnet_ice_event_type_gathering_reflexive_candidates_succeed,
- tnet_ice_event_type_gathering_relay_candidates_failed,
- tnet_ice_event_type_gathering_relay_candidates_succeed,
- tnet_ice_event_type_gathering_completed,
- tnet_ice_event_type_conncheck_succeed,
- tnet_ice_event_type_conncheck_failed,
- tnet_ice_event_type_cancelled,
- tnet_ice_event_type_turn_connection_broken,
+typedef enum tnet_ice_event_type_e {
+ // Public events
+ tnet_ice_event_type_started,
+ tnet_ice_event_type_start_failed,
+ tnet_ice_event_type_stopped,
+ tnet_ice_event_type_stop_failed,
+ tnet_ice_event_type_gathering_host_candidates_failed,
+ tnet_ice_event_type_gathering_host_candidates_succeed,
+ tnet_ice_event_type_gathering_reflexive_candidates_failed,
+ tnet_ice_event_type_gathering_reflexive_candidates_succeed,
+ tnet_ice_event_type_gathering_relay_candidates_failed,
+ tnet_ice_event_type_gathering_relay_candidates_succeed,
+ tnet_ice_event_type_gathering_completed,
+ tnet_ice_event_type_conncheck_succeed,
+ tnet_ice_event_type_conncheck_failed,
+ tnet_ice_event_type_cancelled,
+ tnet_ice_event_type_turn_connection_broken,
- // Private events
- tnet_ice_event_type_action
+ // Private events
+ tnet_ice_event_type_action
}
tnet_ice_event_type_t;
-typedef struct tnet_ice_event_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_ice_event_s {
+ TSK_DECLARE_OBJECT;
- tnet_ice_event_type_t type;
- char* phrase;
- struct tnet_ice_action_s* action;
- const struct tnet_ice_ctx_s* ctx;
+ tnet_ice_event_type_t type;
+ char* phrase;
+ struct tnet_ice_action_s* action;
+ const struct tnet_ice_ctx_s* ctx;
- const void* userdata;
+ const void* userdata;
}
tnet_ice_event_t;
diff --git a/tinyNET/src/ice/tnet_ice_pair.c b/tinyNET/src/ice/tnet_ice_pair.c
index 33e71a5..f917ea2 100755
--- a/tinyNET/src/ice/tnet_ice_pair.c
+++ b/tinyNET/src/ice/tnet_ice_pair.c
@@ -58,7 +58,7 @@
static int __pred_find_by_pair(const tsk_list_item_t *item, const void *pair)
{
- if(item && item->data){
+ if(item && item->data) {
int ret;
tsk_subsat_int32_ptr(item->data, pair, &ret);
return ret;
@@ -70,7 +70,7 @@ static int __pred_find_by_pair(const tsk_list_item_t *item, const void *pair)
static tsk_object_t* tnet_ice_pair_ctor(tsk_object_t * self, va_list * app)
{
tnet_ice_pair_t *pair = self;
- if(pair){
+ if(pair) {
pair->state_offer = tnet_ice_pair_state_frozen;
pair->state_answer = tnet_ice_pair_state_frozen;
}
@@ -90,7 +90,7 @@ static int tnet_ice_pair_cmp(const tsk_object_t *_p1, const tsk_object_t *_p2)
{
const tnet_ice_pair_t *p1 = _p1;
const tnet_ice_pair_t *p2 = _p2;
-
+
if (p1 && p2) {
#if 0
// This is not correct and most differences (if not all) will be equal to "INT_MIN" or "INT_MAX" and this will produce invalid sorting.
@@ -102,11 +102,14 @@ static int tnet_ice_pair_cmp(const tsk_object_t *_p1, const tsk_object_t *_p2)
return (p1->priority == p2->priority) ? 0 : (p1->priority > p2->priority ? 1 : -1);
#endif
}
- else if (!p1 && !p2) return 0;
- else return -1;
+ else if (!p1 && !p2) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
}
-static const tsk_object_def_t tnet_ice_pair_def_s =
-{
+static const tsk_object_def_t tnet_ice_pair_def_s = {
sizeof(tnet_ice_pair_t),
tnet_ice_pair_ctor,
tnet_ice_pair_dtor,
@@ -117,11 +120,11 @@ tnet_ice_pair_t* tnet_ice_pair_create(const tnet_ice_candidate_t* candidate_offe
{
static uint64_t __unique_id = 0;
tnet_ice_pair_t *pair;
- if(!candidate_offer || !candidate_answer){
+ if(!candidate_offer || !candidate_answer) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
+
if ((pair = tsk_object_new(&tnet_ice_pair_def_s))) {
uint64_t G, D;
pair->id = ++__unique_id; // not part of the standard, used to ease debugging
@@ -136,7 +139,7 @@ tnet_ice_pair_t* tnet_ice_pair_create(const tnet_ice_candidate_t* candidate_offe
pair->priority = ((TSK_MIN(G, D)) << 32) + (TSK_MAX(G, D) << 1) + ((G > D) ? 1 : 0);
pair->turn_peer_id = kTurnPeerIdInvalid;
}
-
+
return pair;
}
@@ -148,12 +151,12 @@ tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, tnet_fd_t
const tnet_ice_pair_t *pair_local = tsk_null, *pair = tsk_null;
tnet_ip_t remote_ip;
tnet_port_t remote_port;
-
+
if (!pairs || !remote_addr) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
+
tsk_list_foreach(item, pairs) {
if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_answer || !pair->candidate_offer->socket || pair->candidate_offer->socket->fd != local_fd) {
continue;
@@ -161,12 +164,12 @@ tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, tnet_fd_t
pair_local = pair;
break;
}
-
+
if ((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port))) {
TNET_PRINT_LAST_ERROR("tnet_get_sockip_n_port() failed");
return tsk_null;
}
-
+
if (!pair_local) {
TSK_DEBUG_ERROR("Cannot create prflx candidate with remote ip = %s, remote port = %u and local_fd = %d", remote_ip, remote_port, local_fd);
return tsk_null;
@@ -182,42 +185,42 @@ tnet_ice_pair_t* tnet_ice_pair_prflx_create(tnet_ice_pairs_L_t* pairs, tnet_fd_t
cand_remote->comp_id = pair_local->candidate_offer->comp_id;
memcpy(cand_remote->connection_addr, remote_ip, sizeof(tnet_ip_t));
cand_remote->port = remote_port;
-
+
TSK_DEBUG_INFO("ICE Pair Reflexive Candidate (%llu, %llu): [%s %u %u %s %d] -> [%s %u %u %s %d]",
pair->id,
pair->priority,
-
+
cand_local->foundation,
cand_local->priority,
cand_local->comp_id,
cand_local->connection_addr,
cand_local->port,
-
+
cand_remote->foundation,
cand_remote->priority,
cand_remote->comp_id,
cand_remote->connection_addr,
cand_remote->port);
-
+
pair_peer = tnet_ice_pair_create(cand_local, cand_remote, pair_local->is_controlling, pair_local->tie_breaker, pair_local->is_ice_jingle);
}
TSK_OBJECT_SAFE_FREE(cand_local);
TSK_OBJECT_SAFE_FREE(cand_remote);
return pair_peer;
}
-
+
return tsk_null;
}
int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
{
int ret;
-
- if(!self){
+
+ if(!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
if (self->candidate_offer->turn.ss) {
enum tnet_stun_state_e e_state;
enum tnet_turn_transport_e e_req_transport;
@@ -228,7 +231,7 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
TSK_DEBUG_INFO("TURN CreatePerm not ready yet... to send STUN ConnCheck (peer-id=%ld)", self->turn_peer_id);
goto bail;
}
-
+
if ((ret = tnet_turn_session_get_req_transport(self->candidate_offer->turn.ss, &e_req_transport))) {
goto bail;
}
@@ -244,16 +247,16 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
}
}
}
-
+
if (!self->last_request) {
uint32_t priority;
-
+
// Init remote address
if ((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &self->remote_addr))) {
TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
goto bail;
}
-
+
if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_binding_request, &self->last_request))) {
goto bail;
}
@@ -266,7 +269,7 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
if (self->is_ice_jingle) {
tsk_sprintf(&p_uname, "%s%s", tnet_ice_candidate_get_ufrag(self->candidate_answer), tnet_ice_candidate_get_ufrag(self->candidate_offer));
}
- else{
+ else {
tsk_sprintf(&p_uname, "%s:%s", tnet_ice_candidate_get_ufrag(self->candidate_answer), tnet_ice_candidate_get_ufrag(self->candidate_offer));
}
pc_pwd = tnet_ice_candidate_get_pwd(self->candidate_answer);
@@ -276,7 +279,7 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
goto bail;
}
}
-
+
priority = tnet_ice_utils_get_priority(tnet_ice_cand_type_prflx, self->candidate_offer->local_pref, self->candidate_offer->is_rtp);
// add attributes
self->last_request->opt.dontfrag = 0;
@@ -333,176 +336,176 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
#if TNET_ICE_AGGRESSIVE_NOMINATION
if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_use_candidate)) {
#else
- if (self->is_nominated && !tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_use_candidate)) {
+ if (self->is_nominated && !tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_use_candidate)) {
#endif
- ret = tnet_stun_pkt_attrs_add(self->last_request,
- TNET_STUN_PKT_ATTR_ADD_ICE_USE_CANDIDATE(),
+ ret = tnet_stun_pkt_attrs_add(self->last_request,
+ TNET_STUN_PKT_ATTR_ADD_ICE_USE_CANDIDATE(),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+
+ if (ret) {
+ goto bail;
+ }
+ b_changed = tsk_true;
+ }
+ }
+ else {
+ tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_use_candidate);
+ tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_controlling);
+ if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_controlled)) {
+ ret = tnet_stun_pkt_attrs_add(self->last_request,
+ TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLED(self->tie_breaker),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ b_changed = tsk_true;
+ }
+ }
+ // update transac-id if the request structure changed
+ if ((b_changed && (ret = tnet_stun_utils_transac_id_rand(&self->last_request->transac_id)))) {
+ goto bail;
+ }
+ }
+
+ // Send request
+ {
+ tsk_buffer_t *req_buffer = tsk_null;
+ self->last_request->opt.fingerprint = !self->is_ice_jingle;
+ if ((ret = tnet_stun_pkt_write_with_padding_2(self->last_request, &req_buffer))) {
+ goto bail;
+ }
+ if (self->candidate_offer->turn.ss) {
+ // Send using TURN session. Above, we already checked that the TURN session is ready (Alloc=OK, Permission=OK)
+ ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size);
+ }
+ else {
+ int sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&self->remote_addr, req_buffer->data, req_buffer->size);
+ ret = (sendBytes == req_buffer->size) ? 0 : -9;
+ }
+ TSK_OBJECT_SAFE_FREE(req_buffer);
+ if (ret) {
+ goto bail;
+ }
+ }
+
+bail:
+ if (ret == 0 && self->state_offer == tnet_ice_pair_state_frozen) {
+ self->state_offer = tnet_ice_pair_state_in_progress;
+ }
+ return ret;
+}
+
+int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const short code, const char* phrase, const struct sockaddr_storage *remote_addr)
+{
+ tnet_stun_pkt_t* message = tsk_null;
+ const char *password, *username;
+ int ret = -1;
+ tsk_bool_t is_error = ((code / 100) != 2);
+
+ if(!self || !phrase || !request || !self->candidate_offer || !self->candidate_answer) {
+ TSK_DEBUG_ERROR("Invalid paramter");
+ return -1;
+ }
+
+ username = tsk_null;
+ password = tnet_ice_candidate_get_pwd(self->candidate_offer);
+
+ if ((ret = tnet_stun_pkt_create_empty(is_error ? tnet_stun_pkt_type_binding_error_response : tnet_stun_pkt_type_binding_success_response, &message)) == 0) {
+ tsk_buffer_t *req_buffer = tsk_null;
+ memcpy(message->transac_id, request->transac_id, sizeof(request->transac_id));
+ message->opt.fingerprint = !self->is_ice_jingle;
+ message->opt.dontfrag = 0;
+
+ // SOFWARE
+ ret = tnet_stun_pkt_attrs_add(message,
+ TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+
+ // SHORT-TERM authentication even for responses
+ if ((ret = tnet_stun_pkt_auth_prepare_shortterm_2(message, password))) {
+ goto bail;
+ }
+
+ // ERROR
+ if (is_error) {
+ ret = tnet_stun_pkt_attrs_add(message,
+ TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(((code / 100) & 0x07), (code - ((code / 100) * 100)), phrase),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ else {
+ tnet_ip_t remote_ip;
+ tnet_port_t remote_port;
+ if (self->is_ice_jingle) {
+ const tnet_stun_attr_vdata_t *pc_attr_vdata;
+ // USERNAME
+ if ((ret = tnet_stun_pkt_attr_find_first(request, tnet_stun_attr_type_username, (const tnet_stun_attr_t **)&pc_attr_vdata)) == 0 && pc_attr_vdata) {
+ ret = tnet_stun_pkt_attrs_add(message,
+ TNET_STUN_PKT_ATTR_ADD_USERNAME(pc_attr_vdata->p_data_ptr, pc_attr_vdata->u_data_size),
TNET_STUN_PKT_ATTR_ADD_NULL());
-
if (ret) {
goto bail;
}
- b_changed = tsk_true;
}
}
- else {
- tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_use_candidate);
- tnet_stun_pkt_attr_remove(self->last_request, tnet_stun_attr_type_ice_controlling);
- if (!tnet_stun_pkt_attr_exists(self->last_request, tnet_stun_attr_type_ice_controlled)) {
- ret = tnet_stun_pkt_attrs_add(self->last_request,
- TNET_STUN_PKT_ATTR_ADD_ICE_CONTROLLED(self->tie_breaker),
+ // MAPPED-ADDRESS and XOR-MAPPED-ADDRESS
+ if ((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port)) == 0) {
+ tnet_stun_addr_t _addr;
+ tnet_stun_address_family_t _familly = (remote_addr->ss_family == AF_INET6) ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4;
+ if ((ret = tnet_stun_utils_inet_pton((_familly == tnet_stun_address_family_ipv6), remote_ip, &_addr)) == 0) {
+ ret = tnet_stun_pkt_attrs_add(message,
+ TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS(_familly, remote_port, &_addr),
+ TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS(_familly, remote_port, &_addr),
TNET_STUN_PKT_ATTR_ADD_NULL());
if (ret) {
goto bail;
}
- b_changed = tsk_true;
}
}
- // update transac-id if the request structure changed
- if ((b_changed && (ret = tnet_stun_utils_transac_id_rand(&self->last_request->transac_id)))) {
- goto bail;
- }
}
-
- // Send request
- {
- tsk_buffer_t *req_buffer = tsk_null;
- self->last_request->opt.fingerprint = !self->is_ice_jingle;
- if ((ret = tnet_stun_pkt_write_with_padding_2(self->last_request, &req_buffer))) {
+
+ if (self->candidate_offer->turn.ss) {
+ enum tnet_stun_state_e e_state;
+ if ((ret = tnet_turn_session_get_state_createperm(self->candidate_offer->turn.ss, self->turn_peer_id, &e_state))) {
goto bail;
}
- if (self->candidate_offer->turn.ss) {
- // Send using TURN session. Above, we already checked that the TURN session is ready (Alloc=OK, Permission=OK)
- ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size);
+ if (e_state != tnet_stun_state_ok) {
+ TSK_DEBUG_INFO("TURN CreatePerm not ready yet... to send STUN response (peer-id=%ld)", self->turn_peer_id);
+ goto bail;
}
- else {
- int sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&self->remote_addr, req_buffer->data, req_buffer->size);
- ret = (sendBytes == req_buffer->size) ? 0 : -9;
+ if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
+ goto bail;
}
- TSK_OBJECT_SAFE_FREE(req_buffer);
- if (ret) {
+ if ((ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size))) {
goto bail;
}
}
-
- bail:
- if (ret == 0 && self->state_offer == tnet_ice_pair_state_frozen) {
- self->state_offer = tnet_ice_pair_state_in_progress;
- }
- return ret;
- }
-
- int tnet_ice_pair_send_response(tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const short code, const char* phrase, const struct sockaddr_storage *remote_addr)
- {
- tnet_stun_pkt_t* message = tsk_null;
- const char *password, *username;
- int ret = -1;
- tsk_bool_t is_error = ((code / 100) != 2);
-
- if(!self || !phrase || !request || !self->candidate_offer || !self->candidate_answer){
- TSK_DEBUG_ERROR("Invalid paramter");
- return -1;
- }
-
- username = tsk_null;
- password = tnet_ice_candidate_get_pwd(self->candidate_offer);
-
- if ((ret = tnet_stun_pkt_create_empty(is_error ? tnet_stun_pkt_type_binding_error_response : tnet_stun_pkt_type_binding_success_response, &message)) == 0) {
- tsk_buffer_t *req_buffer = tsk_null;
- memcpy(message->transac_id, request->transac_id, sizeof(request->transac_id));
- message->opt.fingerprint = !self->is_ice_jingle;
- message->opt.dontfrag = 0;
-
- // SOFWARE
- ret = tnet_stun_pkt_attrs_add(message,
- TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
+ else {
+ struct sockaddr_storage dest_addr;
+ int sendBytes;
+ if ((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &dest_addr))) {
+ TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
goto bail;
}
-
- // SHORT-TERM authentication even for responses
- if ((ret = tnet_stun_pkt_auth_prepare_shortterm_2(message, password))) {
+ if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
goto bail;
}
-
- // ERROR
- if (is_error) {
- ret = tnet_stun_pkt_attrs_add(message,
- TNET_STUN_PKT_ATTR_ADD_ERROR_CODE(((code / 100) & 0x07), (code - ((code / 100) * 100)), phrase),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- else {
- tnet_ip_t remote_ip;
- tnet_port_t remote_port;
- if (self->is_ice_jingle) {
- const tnet_stun_attr_vdata_t *pc_attr_vdata;
- // USERNAME
- if ((ret = tnet_stun_pkt_attr_find_first(request, tnet_stun_attr_type_username, (const tnet_stun_attr_t **)&pc_attr_vdata)) == 0 && pc_attr_vdata) {
- ret = tnet_stun_pkt_attrs_add(message,
- TNET_STUN_PKT_ATTR_ADD_USERNAME(pc_attr_vdata->p_data_ptr, pc_attr_vdata->u_data_size),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- // MAPPED-ADDRESS and XOR-MAPPED-ADDRESS
- if ((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port)) == 0) {
- tnet_stun_addr_t _addr;
- tnet_stun_address_family_t _familly = (remote_addr->ss_family == AF_INET6) ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4;
- if ((ret = tnet_stun_utils_inet_pton((_familly == tnet_stun_address_family_ipv6), remote_ip, &_addr)) == 0) {
- ret = tnet_stun_pkt_attrs_add(message,
- TNET_STUN_PKT_ATTR_ADD_MAPPED_ADDRESS(_familly, remote_port, &_addr),
- TNET_STUN_PKT_ATTR_ADD_XOR_MAPPED_ADDRESS(_familly, remote_port, &_addr),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- }
-
- if (self->candidate_offer->turn.ss) {
- enum tnet_stun_state_e e_state;
- if ((ret = tnet_turn_session_get_state_createperm(self->candidate_offer->turn.ss, self->turn_peer_id, &e_state))) {
- goto bail;
- }
- if (e_state != tnet_stun_state_ok) {
- TSK_DEBUG_INFO("TURN CreatePerm not ready yet... to send STUN response (peer-id=%ld)", self->turn_peer_id);
- goto bail;
- }
- if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
- goto bail;
- }
- if ((ret = tnet_turn_session_send_data(self->candidate_offer->turn.ss, self->turn_peer_id, req_buffer->data, (uint16_t)req_buffer->size))) {
- goto bail;
- }
- }
- else {
- struct sockaddr_storage dest_addr;
- int sendBytes;
- if ((ret = tnet_sockaddr_init(self->candidate_answer->connection_addr, self->candidate_answer->port, self->candidate_offer->socket->type, &dest_addr))) {
- TNET_PRINT_LAST_ERROR("tnet_sockaddr_init(%s:%d) failed", self->candidate_answer->connection_addr, self->candidate_answer->port);
- goto bail;
- }
- if ((ret = tnet_stun_pkt_write_with_padding_2(message, &req_buffer))) {
- goto bail;
- }
- sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&dest_addr, req_buffer->data, req_buffer->size);
- TSK_OBJECT_SAFE_FREE(req_buffer);
- ret = (sendBytes > 0) ? 0 : -2;
- if (ret != 0) {
- TSK_DEBUG_ERROR("ICE pair-answer: failed to send response");
- }
+ sendBytes = tnet_sockfd_sendto(self->candidate_offer->socket->fd, (const struct sockaddr*)&dest_addr, req_buffer->data, req_buffer->size);
+ TSK_OBJECT_SAFE_FREE(req_buffer);
+ ret = (sendBytes > 0) ? 0 : -2;
+ if (ret != 0) {
+ TSK_DEBUG_ERROR("ICE pair-answer: failed to send response");
}
}
-
- if (ret == 0 && !is_error) {
- tsk_bool_t change_state =
+ }
+
+ if (ret == 0 && !is_error) {
+ tsk_bool_t change_state =
self->is_ice_jingle // ICE-JINGLE don't have ICE-CONTROLLING/ICE-CONTROLLED attributes
|| (!self->is_controlling && tnet_stun_pkt_attr_exists(request, tnet_stun_attr_type_ice_use_candidate)) // Sender is controlling and uses "ICE-USE-CANDIDATE" attribute
#if TNET_ICE_AGGRESSIVE_NOMINATION || 1 // This is not a typo but a *must*. We've to change the answer state regardless the nomination mode otherwise we'll never get a nominee. Only the offer state is controlled based on the mode and depends on "is_nominated".
@@ -511,301 +514,300 @@ int tnet_ice_pair_send_conncheck(tnet_ice_pair_t *self)
|| (self->is_controlling && self->is_nominated) // We're controlling and using regular mode
#endif
;
- TNET_ICE_PAIR_DEBUG_INFO("ICE pair-answer changing state to 'succeed' ? %s, comp-id=%d, found=%s, addr=%s",
- change_state?"yes":"no",
- self->candidate_answer->comp_id,
- self->candidate_answer->foundation,
- self->candidate_answer->connection_addr
- );
- if (change_state) {
- self->state_answer = tnet_ice_pair_state_succeed;
- }
- }
-
-
- bail:
- TSK_OBJECT_SAFE_FREE(message);
- return ret;
+ TNET_ICE_PAIR_DEBUG_INFO("ICE pair-answer changing state to 'succeed' ? %s, comp-id=%d, found=%s, addr=%s",
+ change_state?"yes":"no",
+ self->candidate_answer->comp_id,
+ self->candidate_answer->foundation,
+ self->candidate_answer->connection_addr
+ );
+ if (change_state) {
+ self->state_answer = tnet_ice_pair_state_succeed;
+ }
}
-
- int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const void* request_buff, tsk_size_t request_buff_size, short* resp_code, char** resp_phrase)
- {
- const uint8_t* _request_buff = (const uint8_t*)request_buff;
-
- const tnet_stun_attr_t* stun_att;
- const tnet_stun_attr_vdata_t *stun_att_usr_name;
- const tnet_stun_attr_vdata_t *stun_att_fingerprint;
- const tnet_stun_attr_vdata_t *stun_att_integrity;
-
- const tsk_list_item_t *item;
- tsk_sha1digest_t hmac;
- const char* pwd;
-
- tsk_size_t msg_integrity_start = 0, length, i;
-
- if(!self || !request || !request_buff || !request_buff_size || !resp_code || !resp_phrase){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if(!TNET_STUN_BUFF_IS_STUN2(_request_buff, request_buff_size)){
- TSK_DEBUG_ERROR("Not STUN buffer");
- return -1;
- }
-
- pwd = tnet_ice_candidate_get_pwd(self->candidate_offer);
- stun_att_usr_name = tsk_null;
- stun_att_fingerprint = tsk_null;
- stun_att_integrity = tsk_null;
-
- tsk_list_foreach(item, request->p_list_attrs) {
- if ((!(stun_att = (const tnet_stun_attr_t*)item->data))) {
- continue;
- }
-
- switch (stun_att->hdr.e_type) {
- case tnet_stun_attr_type_username:
- {
- stun_att_usr_name = (const tnet_stun_attr_vdata_t *)stun_att;
- break;
- }
- case tnet_stun_attr_type_fingerprint:
- {
- stun_att_fingerprint = (const tnet_stun_attr_vdata_t *)stun_att;
- break;
- }
- case tnet_stun_attr_type_message_integrity:
- {
- stun_att_integrity = (const tnet_stun_attr_vdata_t *)stun_att;
- break;
- }
- default: break;
- }
-
- if (!stun_att_integrity) {
- if ((length = (kStunAttrHdrSizeInOctets + stun_att->hdr.u_length)) & 0x03) {
- length += (4 - (length & 0x03));
- }
- msg_integrity_start += length;
- }
+
+
+bail:
+ TSK_OBJECT_SAFE_FREE(message);
+ return ret;
+}
+
+int tnet_ice_pair_auth_conncheck(const tnet_ice_pair_t *self, const tnet_stun_pkt_req_t* request, const void* request_buff, tsk_size_t request_buff_size, short* resp_code, char** resp_phrase)
+{
+ const uint8_t* _request_buff = (const uint8_t*)request_buff;
+
+ const tnet_stun_attr_t* stun_att;
+ const tnet_stun_attr_vdata_t *stun_att_usr_name;
+ const tnet_stun_attr_vdata_t *stun_att_fingerprint;
+ const tnet_stun_attr_vdata_t *stun_att_integrity;
+
+ const tsk_list_item_t *item;
+ tsk_sha1digest_t hmac;
+ const char* pwd;
+
+ tsk_size_t msg_integrity_start = 0, length, i;
+
+ if(!self || !request || !request_buff || !request_buff_size || !resp_code || !resp_phrase) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if(!TNET_STUN_BUFF_IS_STUN2(_request_buff, request_buff_size)) {
+ TSK_DEBUG_ERROR("Not STUN buffer");
+ return -1;
+ }
+
+ pwd = tnet_ice_candidate_get_pwd(self->candidate_offer);
+ stun_att_usr_name = tsk_null;
+ stun_att_fingerprint = tsk_null;
+ stun_att_integrity = tsk_null;
+
+ tsk_list_foreach(item, request->p_list_attrs) {
+ if ((!(stun_att = (const tnet_stun_attr_t*)item->data))) {
+ continue;
}
-
- if (!stun_att_usr_name) {
- TSK_DEBUG_ERROR("USERNAME is missing");
- *resp_code = 400;
- tsk_strupdate(resp_phrase, "USERNAME is missing");
- return -2;
- }
-
- if (!stun_att_integrity || stun_att_integrity->u_data_size != TSK_SHA1_DIGEST_SIZE) {
- if (self->is_ice_jingle) { // Bug introduced in Chrome 20.0.1120.0 (Not security issue as ICE-JINGLE is deprecated and will never be ON)
- *resp_code = 200;
- tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing but accepted");
- return 0;
- }
- else {
- TSK_DEBUG_ERROR("MESSAGE-INTEGRITY is missing");
- *resp_code = 400;
- tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing");
- return -3;
+
+ switch (stun_att->hdr.e_type) {
+ case tnet_stun_attr_type_username: {
+ stun_att_usr_name = (const tnet_stun_attr_vdata_t *)stun_att;
+ break;
+ }
+ case tnet_stun_attr_type_fingerprint: {
+ stun_att_fingerprint = (const tnet_stun_attr_vdata_t *)stun_att;
+ break;
+ }
+ case tnet_stun_attr_type_message_integrity: {
+ stun_att_integrity = (const tnet_stun_attr_vdata_t *)stun_att;
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (!stun_att_integrity) {
+ if ((length = (kStunAttrHdrSizeInOctets + stun_att->hdr.u_length)) & 0x03) {
+ length += (4 - (length & 0x03));
}
+ msg_integrity_start += length;
}
-
- if ((kStunPktHdrSizeInOctets + msg_integrity_start) >= request_buff_size) {
- TSK_DEBUG_ERROR("Invalid length");
- *resp_code = 400;
- tsk_strupdate(resp_phrase, "Invalid length");
- return -20;
- }
-
- if (request->u_length != msg_integrity_start) {
- tsk_size_t size = (kStunPktHdrSizeInOctets + msg_integrity_start);
- uint8_t* new_buffer = (uint8_t*)tsk_calloc(size, 1);
- if (!new_buffer) {
- TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", (unsigned)msg_integrity_start);
- return -30;
- }
- memcpy(new_buffer, request_buff, size);
- length = msg_integrity_start + (kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
- new_buffer[2] = (length >> 8) & 0xFF;
- new_buffer[3] = (length & 0xFF);
- hmac_sha1digest_compute(new_buffer, size, pwd, tsk_strlen(pwd), hmac);
- TSK_FREE(new_buffer);
+ }
+
+ if (!stun_att_usr_name) {
+ TSK_DEBUG_ERROR("USERNAME is missing");
+ *resp_code = 400;
+ tsk_strupdate(resp_phrase, "USERNAME is missing");
+ return -2;
+ }
+
+ if (!stun_att_integrity || stun_att_integrity->u_data_size != TSK_SHA1_DIGEST_SIZE) {
+ if (self->is_ice_jingle) { // Bug introduced in Chrome 20.0.1120.0 (Not security issue as ICE-JINGLE is deprecated and will never be ON)
+ *resp_code = 200;
+ tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing but accepted");
+ return 0;
}
else {
- // must never happen
- hmac_sha1digest_compute(request_buff, request_buff_size, pwd, tsk_strlen(pwd), hmac);
- }
-
- for (i = 0; i < TSK_SHA1_DIGEST_SIZE; ++i) {
- if (hmac[i] != stun_att_integrity->p_data_ptr[i]) {
- TSK_DEBUG_ERROR("MESSAGE-INTEGRITY mismatch");
- *resp_code = 401;
- tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY mismatch");
- return -40;
- }
- }
-
- *resp_code = 200;
- tsk_strupdate(resp_phrase, "Ok");
-
- return 0;
+ TSK_DEBUG_ERROR("MESSAGE-INTEGRITY is missing");
+ *resp_code = 400;
+ tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY is missing");
+ return -3;
+ }
}
-
- int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const tnet_stun_pkt_resp_t* response, tsk_bool_t is_4conncheck)
- {
- if (self && response && TNET_STUN_PKT_IS_RESP(response)) {
- if (self->last_request && tnet_stun_utils_transac_id_equals(self->last_request->transac_id, response->transac_id)){
- // ignore errors (e.g. STALE-CREDENTIALS) which could happen in some special cases before success
- if (TNET_STUN_PKT_RESP_IS_SUCCESS(response)) {
- if (is_4conncheck) {
- self->state_offer = tnet_ice_pair_state_succeed; // we must not change the state after connection cheking to make sure another pair won't be picked as nominated
- TNET_ICE_PAIR_DEBUG_INFO("ICE pair-offer changing state to 'succeed', comp-id=%d, found=%s, addr=%s",
- self->candidate_offer->comp_id,
- self->candidate_offer->foundation,
- self->candidate_offer->connection_addr
- );
- }
+
+ if ((kStunPktHdrSizeInOctets + msg_integrity_start) >= request_buff_size) {
+ TSK_DEBUG_ERROR("Invalid length");
+ *resp_code = 400;
+ tsk_strupdate(resp_phrase, "Invalid length");
+ return -20;
+ }
+
+ if (request->u_length != msg_integrity_start) {
+ tsk_size_t size = (kStunPktHdrSizeInOctets + msg_integrity_start);
+ uint8_t* new_buffer = (uint8_t*)tsk_calloc(size, 1);
+ if (!new_buffer) {
+ TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", (unsigned)msg_integrity_start);
+ return -30;
+ }
+ memcpy(new_buffer, request_buff, size);
+ length = msg_integrity_start + (kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE /* INTEGRITY VALUE*/);
+ new_buffer[2] = (length >> 8) & 0xFF;
+ new_buffer[3] = (length & 0xFF);
+ hmac_sha1digest_compute(new_buffer, size, pwd, tsk_strlen(pwd), hmac);
+ TSK_FREE(new_buffer);
+ }
+ else {
+ // must never happen
+ hmac_sha1digest_compute(request_buff, request_buff_size, pwd, tsk_strlen(pwd), hmac);
+ }
+
+ for (i = 0; i < TSK_SHA1_DIGEST_SIZE; ++i) {
+ if (hmac[i] != stun_att_integrity->p_data_ptr[i]) {
+ TSK_DEBUG_ERROR("MESSAGE-INTEGRITY mismatch");
+ *resp_code = 401;
+ tsk_strupdate(resp_phrase, "MESSAGE-INTEGRITY mismatch");
+ return -40;
+ }
+ }
+
+ *resp_code = 200;
+ tsk_strupdate(resp_phrase, "Ok");
+
+ return 0;
+}
+
+int tnet_ice_pair_recv_response(tnet_ice_pair_t *self, const tnet_stun_pkt_resp_t* response, tsk_bool_t is_4conncheck)
+{
+ if (self && response && TNET_STUN_PKT_IS_RESP(response)) {
+ if (self->last_request && tnet_stun_utils_transac_id_equals(self->last_request->transac_id, response->transac_id)) {
+ // ignore errors (e.g. STALE-CREDENTIALS) which could happen in some special cases before success
+ if (TNET_STUN_PKT_RESP_IS_SUCCESS(response)) {
+ if (is_4conncheck) {
+ self->state_offer = tnet_ice_pair_state_succeed; // we must not change the state after connection cheking to make sure another pair won't be picked as nominated
+ TNET_ICE_PAIR_DEBUG_INFO("ICE pair-offer changing state to 'succeed', comp-id=%d, found=%s, addr=%s",
+ self->candidate_offer->comp_id,
+ self->candidate_offer->foundation,
+ self->candidate_offer->connection_addr
+ );
}
- else {
- // The response is an error
- uint16_t u_code;
- int ret;
- if ((ret = tnet_stun_pkt_get_errorcode(response, &u_code)) == 0 && u_code == kStunErrCodeIceConflict) {
- TSK_DEBUG_INFO("ICE Pair %llu received conflict error message", self->id);
- // If this code is called this means that we have lower tie-breaker and we must toggle our role
- self->is_controlling = !self->is_controlling;
- TSK_OBJECT_SAFE_FREE(self->last_request); // delete the "last_request" to make sure a new one will be created with right attributes
- }
+ }
+ else {
+ // The response is an error
+ uint16_t u_code;
+ int ret;
+ if ((ret = tnet_stun_pkt_get_errorcode(response, &u_code)) == 0 && u_code == kStunErrCodeIceConflict) {
+ TSK_DEBUG_INFO("ICE Pair %llu received conflict error message", self->id);
+ // If this code is called this means that we have lower tie-breaker and we must toggle our role
+ self->is_controlling = !self->is_controlling;
+ TSK_OBJECT_SAFE_FREE(self->last_request); // delete the "last_request" to make sure a new one will be created with right attributes
}
}
}
- return 0;
}
-
- const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs, const tnet_stun_pkt_t* response)
- {
- if(pairs && response){
- const tsk_list_item_t *item;
- const tnet_ice_pair_t *pair;
- tnet_port_t mapped_port;
- tnet_ip_t mapped_ip;
- tsk_list_foreach(item, pairs){
- if(!(pair = item->data) || !pair->candidate_answer || !pair->candidate_offer){
- continue;
+ return 0;
+}
+
+const tnet_ice_pair_t* tnet_ice_pairs_find_by_response(tnet_ice_pairs_L_t* pairs, const tnet_stun_pkt_t* response)
+{
+ if(pairs && response) {
+ const tsk_list_item_t *item;
+ const tnet_ice_pair_t *pair;
+ tnet_port_t mapped_port;
+ tnet_ip_t mapped_ip;
+ tsk_list_foreach(item, pairs) {
+ if(!(pair = item->data) || !pair->candidate_answer || !pair->candidate_offer) {
+ continue;
+ }
+ if(pair->last_request && tnet_stun_utils_transac_id_equals(pair->last_request->transac_id, response->transac_id)) {
+ // check that mapped/xmapped address match destination
+ const tnet_stun_attr_address_t *xmapped_addr = tsk_null;
+ const tnet_stun_attr_address_t* mapped_addr = tsk_null;
+ const tnet_stun_attr_address_t* _addr;
+
+ tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t **)&xmapped_addr);
+ tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t **)&mapped_addr);
+ _addr = xmapped_addr ? xmapped_addr : mapped_addr;
+
+ if (!_addr) {
+ return pair; // do nothing if the client doesn't return mapped address STUN attribute
}
- if(pair->last_request && tnet_stun_utils_transac_id_equals(pair->last_request->transac_id, response->transac_id)){
- // check that mapped/xmapped address match destination
- const tnet_stun_attr_address_t *xmapped_addr = tsk_null;
- const tnet_stun_attr_address_t* mapped_addr = tsk_null;
- const tnet_stun_attr_address_t* _addr;
-
- tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t **)&xmapped_addr);
- tnet_stun_pkt_attr_find_first(response, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t **)&mapped_addr);
- _addr = xmapped_addr ? xmapped_addr : mapped_addr;
-
- if (!_addr) {
- return pair; // do nothing if the client doesn't return mapped address STUN attribute
- }
- /* rfc 5245 7.1.3.2.1. Discovering Peer Reflexive Candidates
-
- The agent checks the mapped address from the STUN response. If the
- transport address does not match any of the local candidates that the
- agent knows about, the mapped address represents a new candidate -- a
- peer reflexive candidate. Like other candidates, it has a type,
- base, priority, and foundation. They are computed as follows:
-
- o Its type is equal to peer reflexive.
-
- o Its base is set equal to the local candidate of the candidate pair
- from which the STUN check was sent.
-
- o Its priority is set equal to the value of the PRIORITY attribute
- in the Binding request.
-
- o Its foundation is selected as described in Section 4.1.1.3.
-
- This peer reflexive candidate is then added to the list of local
- candidates for the media stream. Its username fragment and password
- are the same as all other local candidates for that media stream.
- */
-
- tnet_stun_utils_inet_ntop((_addr->e_family == tnet_stun_address_family_ipv6), &_addr->address, &mapped_ip);
- mapped_port = _addr->u_port;
- if (pair->candidate_offer->type_e != tnet_ice_cand_type_host && (mapped_port != pair->candidate_offer->port || !tsk_striequals(mapped_ip, pair->candidate_offer->connection_addr))) {
- TSK_DEBUG_INFO("Mapped address different than local connection address...probably symetric NAT: %s#%s or %u#%u",
- pair->candidate_offer->connection_addr, mapped_ip,
- pair->candidate_offer->port, mapped_port);
- // do we really need to add new local candidate?
- // continue;
- }
- return pair;
+ /* rfc 5245 7.1.3.2.1. Discovering Peer Reflexive Candidates
+
+ The agent checks the mapped address from the STUN response. If the
+ transport address does not match any of the local candidates that the
+ agent knows about, the mapped address represents a new candidate -- a
+ peer reflexive candidate. Like other candidates, it has a type,
+ base, priority, and foundation. They are computed as follows:
+
+ o Its type is equal to peer reflexive.
+
+ o Its base is set equal to the local candidate of the candidate pair
+ from which the STUN check was sent.
+
+ o Its priority is set equal to the value of the PRIORITY attribute
+ in the Binding request.
+
+ o Its foundation is selected as described in Section 4.1.1.3.
+
+ This peer reflexive candidate is then added to the list of local
+ candidates for the media stream. Its username fragment and password
+ are the same as all other local candidates for that media stream.
+ */
+
+ tnet_stun_utils_inet_ntop((_addr->e_family == tnet_stun_address_family_ipv6), &_addr->address, &mapped_ip);
+ mapped_port = _addr->u_port;
+ if (pair->candidate_offer->type_e != tnet_ice_cand_type_host && (mapped_port != pair->candidate_offer->port || !tsk_striequals(mapped_ip, pair->candidate_offer->connection_addr))) {
+ TSK_DEBUG_INFO("Mapped address different than local connection address...probably symetric NAT: %s#%s or %u#%u",
+ pair->candidate_offer->connection_addr, mapped_ip,
+ pair->candidate_offer->port, mapped_port);
+ // do we really need to add new local candidate?
+ // continue;
}
+ return pair;
}
}
+ }
+ return tsk_null;
+}
+
+const tnet_ice_pair_t* tnet_ice_pairs_find_by_fd_and_addr(tnet_ice_pairs_L_t* pairs, tnet_fd_t local_fd, const struct sockaddr_storage *remote_addr)
+{
+ int ret;
+ const tsk_list_item_t *item;
+ const tnet_ice_pair_t *pair;
+ tnet_ip_t remote_ip;
+ tnet_port_t remote_port;
+
+ if(!pairs || !remote_addr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
- const tnet_ice_pair_t* tnet_ice_pairs_find_by_fd_and_addr(tnet_ice_pairs_L_t* pairs, tnet_fd_t local_fd, const struct sockaddr_storage *remote_addr)
- {
- int ret;
+
+ if((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port))) {
+ TNET_PRINT_LAST_ERROR("tnet_get_sockip_n_port() failed");
+ return tsk_null;
+ }
+
+ tsk_list_foreach(item, pairs) {
+ if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_offer->socket || pair->candidate_offer->socket->fd != local_fd) {
+ continue;
+ }
+ if (!tsk_striequals(pair->candidate_answer->connection_addr, remote_ip) || pair->candidate_answer->port != remote_port) {
+ continue;
+ }
+
+ return pair;
+ }
+
+ TSK_DEBUG_INFO("No ICE candidate with remote ip = %s, port = %u and local_fd = %d could be found...probably symetric NAT", remote_ip, remote_port, local_fd);
+
+ return tsk_null;
+}
+
+
+static tsk_bool_t _tnet_ice_pairs_none_succeed(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id, const char* foundation, tsk_bool_t answer)
+{
+ if(pairs && foundation) {
const tsk_list_item_t *item;
const tnet_ice_pair_t *pair;
- tnet_ip_t remote_ip;
- tnet_port_t remote_port;
-
- if(!pairs || !remote_addr){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
-
- if((ret = tnet_get_sockip_n_port((const struct sockaddr*)remote_addr, &remote_ip, &remote_port))){
- TNET_PRINT_LAST_ERROR("tnet_get_sockip_n_port() failed");
- return tsk_null;
- }
-
- tsk_list_foreach(item, pairs){
- if (!(pair = item->data) || !pair->candidate_offer || !pair->candidate_offer->socket || pair->candidate_offer->socket->fd != local_fd) {
+ const tnet_ice_candidate_t* candidate;
+ tsk_list_foreach(item, pairs) {
+ if(!(pair = item->data) || !(candidate = (answer ? pair->candidate_answer : pair->candidate_offer))) {
continue;
}
- if (!tsk_striequals(pair->candidate_answer->connection_addr, remote_ip) || pair->candidate_answer->port != remote_port) {
+ if(candidate->comp_id != comp_id || !tsk_striequals(candidate->foundation, foundation)) {
continue;
}
-
- return pair;
- }
-
- TSK_DEBUG_INFO("No ICE candidate with remote ip = %s, port = %u and local_fd = %d could be found...probably symetric NAT", remote_ip, remote_port, local_fd);
-
- return tsk_null;
- }
-
-
- static tsk_bool_t _tnet_ice_pairs_none_succeed(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id, const char* foundation, tsk_bool_t answer){
- if(pairs && foundation){
- const tsk_list_item_t *item;
- const tnet_ice_pair_t *pair;
- const tnet_ice_candidate_t* candidate;
- tsk_list_foreach(item, pairs){
- if(!(pair = item->data) || !(candidate = (answer ? pair->candidate_answer : pair->candidate_offer))){
- continue;
- }
- if(candidate->comp_id != comp_id || !tsk_striequals(candidate->foundation, foundation)){
- continue;
- }
- if((answer ? pair->state_answer : pair->state_offer) == tnet_ice_pair_state_succeed){
- TNET_ICE_PAIR_DEBUG_INFO("_tnet_ice_pairs_none_succeed_%s(%u, %s):false", answer?"anwser":"offer", comp_id, foundation);
- return tsk_false;
- }
+ if((answer ? pair->state_answer : pair->state_offer) == tnet_ice_pair_state_succeed) {
+ TNET_ICE_PAIR_DEBUG_INFO("_tnet_ice_pairs_none_succeed_%s(%u, %s):false", answer?"anwser":"offer", comp_id, foundation);
+ return tsk_false;
}
}
- TNET_ICE_PAIR_DEBUG_INFO("_tnet_ice_pairs_none_succeed_%s(%u, %s):true", answer?"anwser":"offer", comp_id, foundation);
- return tsk_true;
}
+ TNET_ICE_PAIR_DEBUG_INFO("_tnet_ice_pairs_none_succeed_%s(%u, %s):true", answer?"anwser":"offer", comp_id, foundation);
+ return tsk_true;
+}
#define _tnet_ice_pairs_none_succeed_answer(pairs, comp_id, foundation) _tnet_ice_pairs_none_succeed((pairs), (comp_id), (foundation), tsk_true)
#define _tnet_ice_pairs_none_succeed_offer(pairs, comp_id, foundation) _tnet_ice_pairs_none_succeed((pairs), (comp_id), (foundation), tsk_false)
-
- // both RTP and RTCP have succeeded
+
+// both RTP and RTCP have succeeded
#define _tnet_ice_pairs_get_nominated_offer_at(pairs, index, comp_id, check_fullness, ret) _tnet_ice_pairs_get_nominated_at((pairs), offer, answer, (index), (comp_id), (check_fullness), (ret))
#define _tnet_ice_pairs_get_nominated_answer_at(pairs, index, comp_id, check_fullness, ret) _tnet_ice_pairs_get_nominated_at((pairs), answer, offer, (index), (comp_id), (check_fullness), (ret))
#define _tnet_ice_pairs_get_nominated_at(pairs, dir_1, dir_2, index, _comp_id, check_fullness, ret) \
@@ -851,138 +853,146 @@ break; \
} \
} \
} \
+
+// true only if both RTP and RTCP are nominated
+tsk_bool_t tnet_ice_pairs_have_nominated_offer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
+{
+ const tnet_ice_pair_t *pair_ = tsk_null;
+ tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
+ TNET_ICE_PAIR_DEBUG_INFO("tnet_ice_pairs_have_nominated_offer()");
+ _tnet_ice_pairs_get_nominated_offer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTP, check_rtcp, (pair_));
+ if((is_nominated_rtp = (pair_ != tsk_null)) && check_rtcp) {
+ _tnet_ice_pairs_get_nominated_offer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTCP, check_rtcp, (pair_));
+ is_nominated_rtcp =(pair_ != tsk_null);
+ }
+ TNET_ICE_PAIR_DEBUG_INFO("is_nominated_rtp_offer=%s, is_nominated_rtcp_offer=%s", is_nominated_rtp?"yes":"no", is_nominated_rtcp?"yes":"no");
+ return (is_nominated_rtp && is_nominated_rtcp);
+}
- // true only if both RTP and RTCP are nominated
- tsk_bool_t tnet_ice_pairs_have_nominated_offer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
- {
- const tnet_ice_pair_t *pair_ = tsk_null;
- tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
- TNET_ICE_PAIR_DEBUG_INFO("tnet_ice_pairs_have_nominated_offer()");
- _tnet_ice_pairs_get_nominated_offer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTP, check_rtcp, (pair_));
- if((is_nominated_rtp = (pair_ != tsk_null)) && check_rtcp){
- _tnet_ice_pairs_get_nominated_offer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTCP, check_rtcp, (pair_));
- is_nominated_rtcp =(pair_ != tsk_null);
- }
- TNET_ICE_PAIR_DEBUG_INFO("is_nominated_rtp_offer=%s, is_nominated_rtcp_offer=%s", is_nominated_rtp?"yes":"no", is_nominated_rtcp?"yes":"no");
- return (is_nominated_rtp && is_nominated_rtcp);
- }
-
- // true only if both RTP and RTCP are nominated
- tsk_bool_t tnet_ice_pairs_have_nominated_answer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
- {
- const tnet_ice_pair_t *pair_ = tsk_null;
- tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
- TNET_ICE_PAIR_DEBUG_INFO("tnet_ice_pairs_have_nominated_answer()");
- _tnet_ice_pairs_get_nominated_answer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTP, check_rtcp, (pair_));
- if((is_nominated_rtp = (pair_ != tsk_null)) && check_rtcp){
- _tnet_ice_pairs_get_nominated_answer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTCP, check_rtcp, (pair_));
- is_nominated_rtcp =(pair_ != tsk_null);
- }
- TNET_ICE_PAIR_DEBUG_INFO("is_nominated_rtp_answer=%s, is_nominated_rtcp_answer=%s", is_nominated_rtp?"yes":"no", is_nominated_rtcp?"yes":"no");
- return (is_nominated_rtp && is_nominated_rtcp);
- }
-
- // true only if both RTP and RTCP are nominated in symetric way
- tsk_bool_t tnet_ice_pairs_have_nominated_symetric_2(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp, tsk_bool_t *got_hosts)
- {
- const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
- tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
- int ret;
-
- if (got_hosts) {
- *got_hosts = tsk_false;
- }
- ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
- if ((is_nominated_rtp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest)) && got_hosts) {
- *got_hosts = (candidate_offer->type_e == tnet_ice_cand_type_host
- && candidate_answer_src->type_e == tnet_ice_cand_type_host
- && candidate_answer_dest->type_e == tnet_ice_cand_type_host);
- }
- if(is_nominated_rtp && check_rtcp){
- ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTCP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
- if ((is_nominated_rtcp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest)) && got_hosts) {
- *got_hosts &= (candidate_offer->type_e == tnet_ice_cand_type_host
- && candidate_answer_src->type_e == tnet_ice_cand_type_host
- && candidate_answer_dest->type_e == tnet_ice_cand_type_host);
- }
+// true only if both RTP and RTCP are nominated
+tsk_bool_t tnet_ice_pairs_have_nominated_answer(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
+{
+ const tnet_ice_pair_t *pair_ = tsk_null;
+ tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
+ TNET_ICE_PAIR_DEBUG_INFO("tnet_ice_pairs_have_nominated_answer()");
+ _tnet_ice_pairs_get_nominated_answer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTP, check_rtcp, (pair_));
+ if((is_nominated_rtp = (pair_ != tsk_null)) && check_rtcp) {
+ _tnet_ice_pairs_get_nominated_answer_at((pairs), 0, TNET_ICE_CANDIDATE_COMPID_RTCP, check_rtcp, (pair_));
+ is_nominated_rtcp =(pair_ != tsk_null);
+ }
+ TNET_ICE_PAIR_DEBUG_INFO("is_nominated_rtp_answer=%s, is_nominated_rtcp_answer=%s", is_nominated_rtp?"yes":"no", is_nominated_rtcp?"yes":"no");
+ return (is_nominated_rtp && is_nominated_rtcp);
+}
+
+// true only if both RTP and RTCP are nominated in symetric way
+tsk_bool_t tnet_ice_pairs_have_nominated_symetric_2(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp, tsk_bool_t *got_hosts)
+{
+ const tnet_ice_candidate_t *candidate_offer, *candidate_answer_src, *candidate_answer_dest;
+ tsk_bool_t is_nominated_rtp, is_nominated_rtcp = tsk_true;
+ int ret;
+
+ if (got_hosts) {
+ *got_hosts = tsk_false;
+ }
+ ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
+ if ((is_nominated_rtp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest)) && got_hosts) {
+ *got_hosts = (candidate_offer->type_e == tnet_ice_cand_type_host
+ && candidate_answer_src->type_e == tnet_ice_cand_type_host
+ && candidate_answer_dest->type_e == tnet_ice_cand_type_host);
+ }
+ if(is_nominated_rtp && check_rtcp) {
+ ret = tnet_ice_pairs_get_nominated_symetric_candidates(pairs, TNET_ICE_CANDIDATE_COMPID_RTCP, &candidate_offer, &candidate_answer_src, &candidate_answer_dest);
+ if ((is_nominated_rtcp = (ret == 0 && candidate_offer && candidate_answer_src && candidate_answer_dest)) && got_hosts) {
+ *got_hosts &= (candidate_offer->type_e == tnet_ice_cand_type_host
+ && candidate_answer_src->type_e == tnet_ice_cand_type_host
+ && candidate_answer_dest->type_e == tnet_ice_cand_type_host);
}
- return (is_nominated_rtp && is_nominated_rtcp);
}
-
- // true only if both RTP and RTCP are nominated in symetric way
- tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
- {
+ return (is_nominated_rtp && is_nominated_rtcp);
+}
+
+// true only if both RTP and RTCP are nominated in symetric way
+tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp)
+{
#define got_hosts tsk_null
- return tnet_ice_pairs_have_nominated_symetric_2(pairs, check_rtcp, got_hosts);
- }
-
- // gets symetric nominated candidates with the highest priority
- // will succeed only if both RTP and RTCP are ok
- int tnet_ice_pairs_get_nominated_symetric_candidates(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
- const tnet_ice_candidate_t** candidate_offer,
- const tnet_ice_candidate_t** candidate_answer_src,
- const tnet_ice_candidate_t** candidate_answer_dest)
- {
- int ret;
- const tnet_ice_pair_t *pair_offer = tsk_null, *pair_answer_src = tsk_null, *pair_answer_dest = tsk_null;
- if (!pairs || !candidate_offer || !candidate_answer_src || !candidate_answer_dest) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- *candidate_offer = tsk_null;
- *candidate_answer_src = tsk_null;
- *candidate_answer_dest = tsk_null;
-
- if ((ret = tnet_ice_pairs_get_nominated_symetric_pairs(pairs, comp_id, &pair_offer, &pair_answer_src, &pair_answer_dest)) == 0) {
- *candidate_offer = pair_offer ? pair_offer->candidate_offer : tsk_null;
- *candidate_answer_src = pair_answer_src ? pair_answer_src->candidate_answer : tsk_null;
- *candidate_answer_dest = pair_answer_dest ? pair_answer_dest->candidate_answer : tsk_null;
- }
- return ret;
+ return tnet_ice_pairs_have_nominated_symetric_2(pairs, check_rtcp, got_hosts);
+}
+
+// gets symetric nominated candidates with the highest priority
+// will succeed only if both RTP and RTCP are ok
+int tnet_ice_pairs_get_nominated_symetric_candidates(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
+ const tnet_ice_candidate_t** candidate_offer,
+ const tnet_ice_candidate_t** candidate_answer_src,
+ const tnet_ice_candidate_t** candidate_answer_dest)
+{
+ int ret;
+ const tnet_ice_pair_t *pair_offer = tsk_null, *pair_answer_src = tsk_null, *pair_answer_dest = tsk_null;
+ if (!pairs || !candidate_offer || !candidate_answer_src || !candidate_answer_dest) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
}
-
- int tnet_ice_pairs_get_nominated_symetric_pairs(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
- const struct tnet_ice_pair_s** _pair_offer,
- const struct tnet_ice_pair_s** _pair_answer_src,
- const struct tnet_ice_pair_s** _pair_answer_dest)
- {
- const tnet_ice_pair_t *pair_offer = tsk_null;
- const tnet_ice_pair_t *pair_answer = tsk_null;
- tsk_size_t i_offer, i_answer;
- static const tsk_bool_t __check_fullness = tsk_false; // pairs will be checked seperatly
-
- if (!pairs || !_pair_offer || !_pair_answer_src || !_pair_answer_dest) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- *_pair_offer = tsk_null;
- *_pair_answer_src = tsk_null;
- *_pair_answer_dest = tsk_null;
-
- i_offer = 0;
+
+ *candidate_offer = tsk_null;
+ *candidate_answer_src = tsk_null;
+ *candidate_answer_dest = tsk_null;
+
+ if ((ret = tnet_ice_pairs_get_nominated_symetric_pairs(pairs, comp_id, &pair_offer, &pair_answer_src, &pair_answer_dest)) == 0) {
+ *candidate_offer = pair_offer ? pair_offer->candidate_offer : tsk_null;
+ *candidate_answer_src = pair_answer_src ? pair_answer_src->candidate_answer : tsk_null;
+ *candidate_answer_dest = pair_answer_dest ? pair_answer_dest->candidate_answer : tsk_null;
+ }
+ return ret;
+}
+
+int tnet_ice_pairs_get_nominated_symetric_pairs(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
+ const struct tnet_ice_pair_s** _pair_offer,
+ const struct tnet_ice_pair_s** _pair_answer_src,
+ const struct tnet_ice_pair_s** _pair_answer_dest)
+{
+ const tnet_ice_pair_t *pair_offer = tsk_null;
+ const tnet_ice_pair_t *pair_answer = tsk_null;
+ tsk_size_t i_offer, i_answer;
+ static const tsk_bool_t __check_fullness = tsk_false; // pairs will be checked seperatly
+
+ if (!pairs || !_pair_offer || !_pair_answer_src || !_pair_answer_dest) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ *_pair_offer = tsk_null;
+ *_pair_answer_src = tsk_null;
+ *_pair_answer_dest = tsk_null;
+
+ i_offer = 0;
+ while (1) {
+ _tnet_ice_pairs_get_nominated_offer_at((pairs), i_offer, comp_id, __check_fullness, (pair_offer)); // pair with socket SO as sender
+ if(!pair_offer) {
+ return 0;
+ }
+ ++i_offer;
+ if (pair_offer->candidate_offer->comp_id != comp_id) {
+ continue;
+ }
+ // find another pair with socket SO as receiver
+
+ i_answer = 0;
while (1) {
- _tnet_ice_pairs_get_nominated_offer_at((pairs), i_offer, comp_id, __check_fullness, (pair_offer)); // pair with socket SO as sender
- if(!pair_offer) return 0;
- ++i_offer;
- if (pair_offer->candidate_offer->comp_id != comp_id) continue;
- // find another pair with socket SO as receiver
-
- i_answer = 0;
- while (1) {
- _tnet_ice_pairs_get_nominated_answer_at((pairs), i_answer, comp_id, __check_fullness, (pair_answer));
- if (!pair_answer) break;
- ++i_answer;
- if (pair_answer->candidate_offer->comp_id != comp_id) continue;
- if (pair_answer->candidate_offer == pair_offer->candidate_offer) {
- *_pair_offer = pair_offer;
- *_pair_answer_src = pair_answer;
- *_pair_answer_dest = pair_offer;
- return 0;
- }
+ _tnet_ice_pairs_get_nominated_answer_at((pairs), i_answer, comp_id, __check_fullness, (pair_answer));
+ if (!pair_answer) {
+ break;
+ }
+ ++i_answer;
+ if (pair_answer->candidate_offer->comp_id != comp_id) {
+ continue;
+ }
+ if (pair_answer->candidate_offer == pair_offer->candidate_offer) {
+ *_pair_offer = pair_offer;
+ *_pair_answer_src = pair_answer;
+ *_pair_answer_dest = pair_offer;
+ return 0;
}
}
- return 0;
-
}
+ return 0;
+
+}
diff --git a/tinyNET/src/ice/tnet_ice_pair.h b/tinyNET/src/ice/tnet_ice_pair.h
index 7e40eb8..f3fb73d 100755
--- a/tinyNET/src/ice/tnet_ice_pair.h
+++ b/tinyNET/src/ice/tnet_ice_pair.h
@@ -8,12 +8,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -32,33 +32,31 @@ typedef tsk_list_t tnet_ice_pairs_L_t;
struct tnet_ice_candidate_s;
-typedef enum tnet_ice_pair_state_e
-{
- tnet_ice_pair_state_frozen,
- tnet_ice_pair_state_waiting,
- tnet_ice_pair_state_in_progress,
- tnet_ice_pair_state_succeed,
- tnet_ice_pair_state_failed
+typedef enum tnet_ice_pair_state_e {
+ tnet_ice_pair_state_frozen,
+ tnet_ice_pair_state_waiting,
+ tnet_ice_pair_state_in_progress,
+ tnet_ice_pair_state_succeed,
+ tnet_ice_pair_state_failed
}
tnet_ice_pair_state_t;
-typedef struct tnet_ice_pair_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_ice_pair_s {
+ TSK_DECLARE_OBJECT;
- uint64_t id;
- uint64_t priority;
- tnet_ice_pair_state_t state_offer;
- tnet_ice_pair_state_t state_answer;
- tsk_bool_t is_ice_jingle;
- tsk_bool_t is_controlling;
- tsk_bool_t is_nominated;
- uint64_t tie_breaker;
- struct tnet_ice_candidate_s* candidate_offer;
- struct tnet_ice_candidate_s* candidate_answer;
- struct tnet_stun_pkt_s* last_request;
- struct sockaddr_storage remote_addr;
- tnet_turn_peer_id_t turn_peer_id;
+ uint64_t id;
+ uint64_t priority;
+ tnet_ice_pair_state_t state_offer;
+ tnet_ice_pair_state_t state_answer;
+ tsk_bool_t is_ice_jingle;
+ tsk_bool_t is_controlling;
+ tsk_bool_t is_nominated;
+ uint64_t tie_breaker;
+ struct tnet_ice_candidate_s* candidate_offer;
+ struct tnet_ice_candidate_s* candidate_answer;
+ struct tnet_stun_pkt_s* last_request;
+ struct sockaddr_storage remote_addr;
+ tnet_turn_peer_id_t turn_peer_id;
}
tnet_ice_pair_t;
@@ -75,12 +73,12 @@ tsk_bool_t tnet_ice_pairs_have_nominated_answer(const tnet_ice_pairs_L_t* pairs,
tsk_bool_t tnet_ice_pairs_have_nominated_symetric(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp);
tsk_bool_t tnet_ice_pairs_have_nominated_symetric_2(const tnet_ice_pairs_L_t* pairs, tsk_bool_t check_rtcp, tsk_bool_t *got_hosts);
int tnet_ice_pairs_get_nominated_symetric_candidates(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
- const struct tnet_ice_candidate_s** candidate_offer,
- const struct tnet_ice_candidate_s** candidate_answer_src,
- const struct tnet_ice_candidate_s** candidate_answer_dest);
+ const struct tnet_ice_candidate_s** candidate_offer,
+ const struct tnet_ice_candidate_s** candidate_answer_src,
+ const struct tnet_ice_candidate_s** candidate_answer_dest);
int tnet_ice_pairs_get_nominated_symetric_pairs(const tnet_ice_pairs_L_t* pairs, uint32_t comp_id,
- const struct tnet_ice_pair_s** pair_offer,
- const struct tnet_ice_pair_s** pair_answer_src,
- const struct tnet_ice_pair_s** pair_answer_dest);
+ const struct tnet_ice_pair_s** pair_offer,
+ const struct tnet_ice_pair_s** pair_answer_src,
+ const struct tnet_ice_pair_s** pair_answer_dest);
#endif /* TNET_ICE_PAIR_H */
diff --git a/tinyNET/src/ice/tnet_ice_utils.c b/tinyNET/src/ice/tnet_ice_utils.c
index d4ba8a7..eae514e 100755
--- a/tinyNET/src/ice/tnet_ice_utils.c
+++ b/tinyNET/src/ice/tnet_ice_utils.c
@@ -8,12 +8,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -29,132 +29,144 @@
#include <stdlib.h>
-static const char ice_chars[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'k', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'K', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- '0','1', '2', '3', '4', '5', '6', '7', '8', '9'}; // /!\do not add '/' and '+' because of WebRTC password
+static const char ice_chars[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'k', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'K', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ '0','1', '2', '3', '4', '5', '6', '7', '8', '9'
+ }; // /!\do not add '/' and '+' because of WebRTC password
static const tsk_size_t ice_chars_count = sizeof(ice_chars);
uint32_t tnet_ice_utils_get_priority(tnet_ice_cand_type_t type, uint16_t local_pref, tsk_bool_t is_rtp)
{
- uint32_t pref;
- switch(type){
- case tnet_ice_cand_type_host: pref = TNET_ICE_CANDIDATE_PREF_HOST; break;
- case tnet_ice_cand_type_srflx: pref = TNET_ICE_CANDIDATE_PREF_SRFLX; break;
- case tnet_ice_cand_type_prflx: pref = TNET_ICE_CANDIDATE_PREF_PRFLX; break;
- case tnet_ice_cand_type_relay: default: pref = TNET_ICE_CANDIDATE_PREF_RELAY; break;
- }
- return (pref << 24) +
- (local_pref << 8) +
- ((256 - (is_rtp ? TNET_ICE_CANDIDATE_COMPID_RTP : TNET_ICE_CANDIDATE_COMPID_RTCP)) << 0);
+ uint32_t pref;
+ switch(type) {
+ case tnet_ice_cand_type_host:
+ pref = TNET_ICE_CANDIDATE_PREF_HOST;
+ break;
+ case tnet_ice_cand_type_srflx:
+ pref = TNET_ICE_CANDIDATE_PREF_SRFLX;
+ break;
+ case tnet_ice_cand_type_prflx:
+ pref = TNET_ICE_CANDIDATE_PREF_PRFLX;
+ break;
+ case tnet_ice_cand_type_relay:
+ default:
+ pref = TNET_ICE_CANDIDATE_PREF_RELAY;
+ break;
+ }
+ return (pref << 24) +
+ (local_pref << 8) +
+ ((256 - (is_rtp ? TNET_ICE_CANDIDATE_COMPID_RTP : TNET_ICE_CANDIDATE_COMPID_RTCP)) << 0);
}
int tnet_ice_utils_compute_foundation(char* foundation, tsk_size_t size)
{
-
- tsk_size_t i;
-
- if(!foundation || !size){
- TSK_DEBUG_ERROR("Invalid argument");
- return -1;
- }
- for(
- i = 0; i < size; ++i){
- foundation[i] = ice_chars[(rand() ^ rand()) % ice_chars_count];
- }
-
- return 0;
+
+ tsk_size_t i;
+
+ if(!foundation || !size) {
+ TSK_DEBUG_ERROR("Invalid argument");
+ return -1;
+ }
+ for(
+ i = 0; i < size; ++i) {
+ foundation[i] = ice_chars[(rand() ^ rand()) % ice_chars_count];
+ }
+
+ return 0;
}
int tnet_ice_utils_create_sockets(tnet_socket_type_t socket_type, const char* local_ip, tnet_socket_t** socket_rtp, tnet_socket_t** socket_rtcp)
{
- tsk_bool_t look4_rtp = (socket_rtp != tsk_null);
- tsk_bool_t look4_rtcp = (socket_rtcp != tsk_null);
- uint8_t retry_count = 10;
- tnet_port_t local_port;
- static const uint64_t port_range_start = 1024;
- static const uint64_t port_range_stop = (65535 - 1/* to be sure rtcp port will be valid */);
- static uint64_t counter = 0;
-
- /* Creates local rtp and rtcp sockets */
- while(retry_count--){
- if(look4_rtp && look4_rtcp){
- tnet_socket_t* socket_fake = tnet_socket_create(local_ip, TNET_SOCKET_PORT_ANY, socket_type);
- if(!socket_fake){
- continue;
- }
- if(!(socket_fake->port & 0x01)){ // even number ?
- *socket_rtp = socket_fake;
- }
- else{
- *socket_rtcp = socket_fake;
- }
- local_port = (socket_fake->port & ~1);
- }
- else{
- local_port = (tnet_port_t)((((tsk_time_epoch() + rand() ) ^ ++counter) % (port_range_stop - port_range_start)) + port_range_start);
- local_port = (local_port & 0xFFFE); /* turn to even number */
- }
-
- /* beacuse failure will cause errors in the log, print a message to alert that there is
- * nothing to worry about */
- TSK_DEBUG_INFO("RTP/RTCP manager[Begin]: Trying to bind to random ports [%s:%d]", local_ip, local_port);
-
- if(look4_rtp){
- if(!*socket_rtp && !(*socket_rtp = tnet_socket_create(local_ip, local_port, socket_type))){
- TSK_DEBUG_INFO("Failed to bind to %d", local_port);
- continue;
- }
- }
-
- if(look4_rtcp){
- if(!*socket_rtcp && !(*socket_rtcp = tnet_socket_create(local_ip, (local_port + 1), socket_type))){
- TSK_DEBUG_INFO("Failed to bind to %d", (local_port + 1));
- if(look4_rtp){
- TSK_OBJECT_SAFE_FREE((*socket_rtp));
- }
- continue;
- }
- }
-
- TSK_DEBUG_INFO("RTP/RTCP manager[End]: Trying to bind to random ports");
- return 0;
- }
-
- TSK_DEBUG_ERROR("Failed to bind sockets");
- return -1;
+ tsk_bool_t look4_rtp = (socket_rtp != tsk_null);
+ tsk_bool_t look4_rtcp = (socket_rtcp != tsk_null);
+ uint8_t retry_count = 10;
+ tnet_port_t local_port;
+ static const uint64_t port_range_start = 1024;
+ static const uint64_t port_range_stop = (65535 - 1/* to be sure rtcp port will be valid */);
+ static uint64_t counter = 0;
+
+ /* Creates local rtp and rtcp sockets */
+ while(retry_count--) {
+ if(look4_rtp && look4_rtcp) {
+ tnet_socket_t* socket_fake = tnet_socket_create(local_ip, TNET_SOCKET_PORT_ANY, socket_type);
+ if(!socket_fake) {
+ continue;
+ }
+ if(!(socket_fake->port & 0x01)) { // even number ?
+ *socket_rtp = socket_fake;
+ }
+ else {
+ *socket_rtcp = socket_fake;
+ }
+ local_port = (socket_fake->port & ~1);
+ }
+ else {
+ local_port = (tnet_port_t)((((tsk_time_epoch() + rand() ) ^ ++counter) % (port_range_stop - port_range_start)) + port_range_start);
+ local_port = (local_port & 0xFFFE); /* turn to even number */
+ }
+
+ /* beacuse failure will cause errors in the log, print a message to alert that there is
+ * nothing to worry about */
+ TSK_DEBUG_INFO("RTP/RTCP manager[Begin]: Trying to bind to random ports [%s:%d]", local_ip, local_port);
+
+ if(look4_rtp) {
+ if(!*socket_rtp && !(*socket_rtp = tnet_socket_create(local_ip, local_port, socket_type))) {
+ TSK_DEBUG_INFO("Failed to bind to %d", local_port);
+ continue;
+ }
+ }
+
+ if(look4_rtcp) {
+ if(!*socket_rtcp && !(*socket_rtcp = tnet_socket_create(local_ip, (local_port + 1), socket_type))) {
+ TSK_DEBUG_INFO("Failed to bind to %d", (local_port + 1));
+ if(look4_rtp) {
+ TSK_OBJECT_SAFE_FREE((*socket_rtp));
+ }
+ continue;
+ }
+ }
+
+ TSK_DEBUG_INFO("RTP/RTCP manager[End]: Trying to bind to random ports");
+ return 0;
+ }
+
+ TSK_DEBUG_ERROR("Failed to bind sockets");
+ return -1;
}
int tnet_ice_utils_set_ufrag(char** ufrag)
{
- if(ufrag){
- char tmp[16]; int i;
- for(i = 0; i < (sizeof(tmp)/sizeof(tmp[0])) - 1; ++i){
- tmp[i] = ice_chars[(rand() ^ rand()) % ice_chars_count];
- }
- tmp[i] = '\0';
- tsk_strupdate(ufrag, tmp);
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if(ufrag) {
+ char tmp[16];
+ int i;
+ for(i = 0; i < (sizeof(tmp)/sizeof(tmp[0])) - 1; ++i) {
+ tmp[i] = ice_chars[(rand() ^ rand()) % ice_chars_count];
+ }
+ tmp[i] = '\0';
+ tsk_strupdate(ufrag, tmp);
+ return 0;
+ }
+ else {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
}
int tnet_ice_utils_set_pwd(char** pwd)
{
- if(pwd){
- char tmp[23]; int i;
- for(i = 0; i < (sizeof(tmp)/sizeof(tmp[0])) - 1; ++i){
- tmp[i] = ice_chars[(rand() ^ rand()) % ice_chars_count];
- }
- tmp[i] = '\0';
- tsk_strupdate(pwd, tmp);
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if(pwd) {
+ char tmp[23];
+ int i;
+ for(i = 0; i < (sizeof(tmp)/sizeof(tmp[0])) - 1; ++i) {
+ tmp[i] = ice_chars[(rand() ^ rand()) % ice_chars_count];
+ }
+ tmp[i] = '\0';
+ tsk_strupdate(pwd, tmp);
+ return 0;
+ }
+ else {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
} \ No newline at end of file
diff --git a/tinyNET/src/ice/tnet_ice_utils.h b/tinyNET/src/ice/tnet_ice_utils.h
index 8e53915..541bb9a 100755
--- a/tinyNET/src/ice/tnet_ice_utils.h
+++ b/tinyNET/src/ice/tnet_ice_utils.h
@@ -8,12 +8,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/stun/tnet_stun_attr.c b/tinyNET/src/stun/tnet_stun_attr.c
index 4c31c05..25ad6c7 100755
--- a/tinyNET/src/stun/tnet_stun_attr.c
+++ b/tinyNET/src/stun/tnet_stun_attr.c
@@ -53,479 +53,479 @@
static int _tnet_stun_attr_cmp(const tsk_object_t *_att1, const tsk_object_t *_att2)
{
- const tnet_stun_attr_t *pc_att1 = (const tnet_stun_attr_t *)_att1;
- const tnet_stun_attr_t *pc_att2 = (const tnet_stun_attr_t *)_att2;
+ const tnet_stun_attr_t *pc_att1 = (const tnet_stun_attr_t *)_att1;
+ const tnet_stun_attr_t *pc_att2 = (const tnet_stun_attr_t *)_att2;
- return (int)(pc_att1 - pc_att2);
+ return (int)(pc_att1 - pc_att2);
}
static int _tnet_stun_attr_get_size_in_octetunits(const tnet_stun_attr_t* pc_self, tsk_bool_t with_padding, tsk_size_t* p_size)
{
- if (!pc_self || !p_size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- switch (pc_self->hdr.e_type) {
- case tnet_stun_attr_type_mapped_address:
- case tnet_stun_attr_type_alternate_server:
- case tnet_stun_attr_type_xor_mapped_address:
- case tnet_stun_attr_type_xor_peer_address:
- case tnet_stun_attr_type_xor_relayed_address: {
- extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
- const tnet_stun_attr_address_t* _pc_self = (const tnet_stun_attr_address_t*)pc_self;
- if (pc_self->__def__ != tnet_stun_attr_address_def_t) {
- TSK_DEBUG_ERROR("Invalid base type");
- return -2;
- }
- *p_size = (kStunAttrHdrSizeInOctets + 1/*Ignored*/ + 1/*Family*/ + 2/*Port*/ + ((_pc_self->e_family == tnet_stun_address_family_ipv6) ? 16 : 4));
- if (with_padding) {
- ALIGN_ON_32BITS(*p_size);
- }
- return 0;
- }
- case tnet_stun_attr_type_data:
- case tnet_stun_attr_type_unknown_attrs:
- case tnet_stun_attr_type_dont_fragment:
- case tnet_stun_attr_type_software:
- case tnet_stun_attr_type_nonce:
- case tnet_stun_attr_type_realm:
- case tnet_stun_attr_type_username:
- case tnet_stun_attr_type_password:
- case tnet_stun_attr_type_channel_number:
- case tnet_stun_attr_type_message_integrity:
- case tnet_stun_attr_type_fingerprint:
- case tnet_stun_attr_type_lifetime:
- case tnet_stun_attr_type_requested_transport:
- case tnet_stun_attr_type_ice_use_candidate:
- case tnet_stun_attr_type_ice_priority:
- case tnet_stun_attr_type_ice_controlled:
- case tnet_stun_attr_type_ice_controlling:
- case tnet_stun_attr_type_connection_id: {
- extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
- const tnet_stun_attr_vdata_t* _pc_self = (const tnet_stun_attr_vdata_t*)pc_self;
- if (pc_self->__def__ != tnet_stun_attr_vdata_def_t) {
- TSK_DEBUG_ERROR("Invalid base type");
- return -2;
- }
- *p_size = (kStunAttrHdrSizeInOctets + _pc_self->u_data_size);
- if (with_padding) {
- ALIGN_ON_32BITS(*p_size);
- }
- return 0;
- }
- case tnet_stun_attr_type_error_code: {
- const tnet_stun_attr_error_code_t* _pc_self = (const tnet_stun_attr_error_code_t*)pc_self;
- *p_size = (kStunAttrHdrSizeInOctets + 4 + (tsk_size_t)tsk_strlen(_pc_self->p_reason_phrase));
- if (with_padding) {
- ALIGN_ON_32BITS(*p_size);
- }
- return 0;
- }
- default: {
- TSK_DEBUG_WARN("Attribute type=%d is unknown. Don't be surprised if something goes wrong.", pc_self->hdr.e_type);
- *p_size = (kStunAttrHdrSizeInOctets + pc_self->hdr.u_length);
- if (with_padding) {
- ALIGN_ON_32BITS(*p_size);
- }
- return 0;
- }
- }
+ if (!pc_self || !p_size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ switch (pc_self->hdr.e_type) {
+ case tnet_stun_attr_type_mapped_address:
+ case tnet_stun_attr_type_alternate_server:
+ case tnet_stun_attr_type_xor_mapped_address:
+ case tnet_stun_attr_type_xor_peer_address:
+ case tnet_stun_attr_type_xor_relayed_address: {
+ extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
+ const tnet_stun_attr_address_t* _pc_self = (const tnet_stun_attr_address_t*)pc_self;
+ if (pc_self->__def__ != tnet_stun_attr_address_def_t) {
+ TSK_DEBUG_ERROR("Invalid base type");
+ return -2;
+ }
+ *p_size = (kStunAttrHdrSizeInOctets + 1/*Ignored*/ + 1/*Family*/ + 2/*Port*/ + ((_pc_self->e_family == tnet_stun_address_family_ipv6) ? 16 : 4));
+ if (with_padding) {
+ ALIGN_ON_32BITS(*p_size);
+ }
+ return 0;
+ }
+ case tnet_stun_attr_type_data:
+ case tnet_stun_attr_type_unknown_attrs:
+ case tnet_stun_attr_type_dont_fragment:
+ case tnet_stun_attr_type_software:
+ case tnet_stun_attr_type_nonce:
+ case tnet_stun_attr_type_realm:
+ case tnet_stun_attr_type_username:
+ case tnet_stun_attr_type_password:
+ case tnet_stun_attr_type_channel_number:
+ case tnet_stun_attr_type_message_integrity:
+ case tnet_stun_attr_type_fingerprint:
+ case tnet_stun_attr_type_lifetime:
+ case tnet_stun_attr_type_requested_transport:
+ case tnet_stun_attr_type_ice_use_candidate:
+ case tnet_stun_attr_type_ice_priority:
+ case tnet_stun_attr_type_ice_controlled:
+ case tnet_stun_attr_type_ice_controlling:
+ case tnet_stun_attr_type_connection_id: {
+ extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
+ const tnet_stun_attr_vdata_t* _pc_self = (const tnet_stun_attr_vdata_t*)pc_self;
+ if (pc_self->__def__ != tnet_stun_attr_vdata_def_t) {
+ TSK_DEBUG_ERROR("Invalid base type");
+ return -2;
+ }
+ *p_size = (kStunAttrHdrSizeInOctets + _pc_self->u_data_size);
+ if (with_padding) {
+ ALIGN_ON_32BITS(*p_size);
+ }
+ return 0;
+ }
+ case tnet_stun_attr_type_error_code: {
+ const tnet_stun_attr_error_code_t* _pc_self = (const tnet_stun_attr_error_code_t*)pc_self;
+ *p_size = (kStunAttrHdrSizeInOctets + 4 + (tsk_size_t)tsk_strlen(_pc_self->p_reason_phrase));
+ if (with_padding) {
+ ALIGN_ON_32BITS(*p_size);
+ }
+ return 0;
+ }
+ default: {
+ TSK_DEBUG_WARN("Attribute type=%d is unknown. Don't be surprised if something goes wrong.", pc_self->hdr.e_type);
+ *p_size = (kStunAttrHdrSizeInOctets + pc_self->hdr.u_length);
+ if (with_padding) {
+ ALIGN_ON_32BITS(*p_size);
+ }
+ return 0;
+ }
+ }
}
static int _tnet_stun_attr_write(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t with_padding, tsk_size_t *p_written)
{
- tsk_size_t n_min_req_size;
- int ret;
- if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if ((ret = _tnet_stun_attr_get_size_in_octetunits(pc_self, with_padding, &n_min_req_size))) {
- return ret;
- }
- if (n_min_req_size > n_buff_size) {
- TSK_DEBUG_ERROR("Buffer too short %u<%u", (unsigned)n_buff_size, (unsigned)n_min_req_size);
- return -2;
- }
-
- *((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->hdr.e_type);
- // *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)pc_self->hdr.u_length);
- *p_written = kStunAttrHdrSizeInOctets;
-
- switch (pc_self->hdr.e_type) {
- case tnet_stun_attr_type_mapped_address:
- case tnet_stun_attr_type_alternate_server:
- case tnet_stun_attr_type_xor_mapped_address:
- case tnet_stun_attr_type_xor_peer_address:
- case tnet_stun_attr_type_xor_relayed_address: {
- tsk_size_t u_addr_size;
- extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
- const tnet_stun_attr_address_t* _pc_self = (const tnet_stun_attr_address_t*)pc_self;
- tsk_bool_t b_xor = IS_ADDRESS_XOR(pc_self->hdr.e_type);
- if (pc_self->__def__ != tnet_stun_attr_address_def_t) {
- TSK_DEBUG_ERROR("Invalid base type");
- return -2;
- }
- p_buff_ptr[*p_written] = 0x00; // Reserved
- p_buff_ptr[*p_written + 1] = _pc_self->e_family;
- u_addr_size = (_pc_self->e_family == tnet_stun_address_family_ipv6 ? 16 : 4);
- if (b_xor) {
- tsk_size_t u;
- *((uint16_t*)&p_buff_ptr[*p_written + 2]) = tnet_htons(_pc_self->u_port ^ kStunMagicCookieShort);
- *((uint32_t*)&p_buff_ptr[*p_written + 4]) = (uint32_t)tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[0])) ^ kStunMagicCookieLong);
- for (u = 4; u < u_addr_size; u += 4) {
- if (pc_transac_id) {
- *((uint32_t*)&p_buff_ptr[*p_written + 4 + u]) = (uint32_t)tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[u])) ^ tnet_ntohl(*((uint32_t*)(*pc_transac_id + u - 4))));
- }
- else {
- *((uint32_t*)&p_buff_ptr[*p_written + 4 + u]) = (uint32_t)tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[u])) ^ 0);
- }
- }
- }
- else {
- *((uint16_t*)&p_buff_ptr[*p_written + 2]) = tnet_htons(_pc_self->u_port);
- memcpy(&p_buff_ptr[*p_written + 4], _pc_self->address, u_addr_size);
- }
-
- *p_written += 4 + u_addr_size;
- *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
- if (with_padding) {
- ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
- }
- return 0;
- }
-
- case tnet_stun_attr_type_data:
- case tnet_stun_attr_type_unknown_attrs:
- case tnet_stun_attr_type_dont_fragment:
- case tnet_stun_attr_type_software:
- case tnet_stun_attr_type_nonce:
- case tnet_stun_attr_type_realm:
- case tnet_stun_attr_type_username:
- case tnet_stun_attr_type_password:
- case tnet_stun_attr_type_channel_number:
- case tnet_stun_attr_type_message_integrity:
- case tnet_stun_attr_type_fingerprint:
- case tnet_stun_attr_type_lifetime:
- case tnet_stun_attr_type_requested_transport:
- case tnet_stun_attr_type_ice_use_candidate:
- case tnet_stun_attr_type_ice_priority:
- case tnet_stun_attr_type_ice_controlled:
- case tnet_stun_attr_type_ice_controlling:
- case tnet_stun_attr_type_connection_id: {
- extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
- const tnet_stun_attr_vdata_t* _pc_self = (const tnet_stun_attr_vdata_t*)pc_self;
- if (pc_self->__def__ != tnet_stun_attr_vdata_def_t) {
- TSK_DEBUG_ERROR("Invalid base type");
- return -2;
- }
- if (_pc_self->p_data_ptr && _pc_self->u_data_size) {
- if (IS_VDATA_UINT16(pc_self->hdr.e_type) && _pc_self->u_data_size == 2) {
- *((uint16_t*)&p_buff_ptr[*p_written]) = tnet_htons_2(&_pc_self->p_data_ptr[0]);
- }
- else if (IS_VDATA_UINT32(pc_self->hdr.e_type) && _pc_self->u_data_size == 4) {
- *((uint32_t*)&p_buff_ptr[*p_written]) = (uint32_t)tnet_htonl_2(&_pc_self->p_data_ptr[0]);
- }
- else if (IS_VDATA_UINT64(pc_self->hdr.e_type) && _pc_self->u_data_size == 8) {
- *((uint32_t*)&p_buff_ptr[*p_written]) = (uint32_t)tnet_htonl_2(&_pc_self->p_data_ptr[0]);
- *((uint32_t*)&p_buff_ptr[*p_written + 4]) = (uint32_t)tnet_htonl_2(&_pc_self->p_data_ptr[4]);
- }
- else if (pc_self->hdr.e_type == tnet_stun_attr_type_unknown_attrs && _pc_self->u_data_size && !(_pc_self->u_data_size & 1)) {
- uint16_t u;
- for (u = 0; u < _pc_self->u_data_size; u += 2) {
- *((uint16_t*)&p_buff_ptr[*p_written + u]) = tnet_htons_2(&_pc_self->p_data_ptr[u]);
- }
- }
- else {
- memcpy(&p_buff_ptr[*p_written], _pc_self->p_data_ptr, _pc_self->u_data_size);
- }
- *p_written += _pc_self->u_data_size;
- }
- if (with_padding) {
- ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
- }
- *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
- return 0;
- }
- case tnet_stun_attr_type_error_code: {
- const tnet_stun_attr_error_code_t* _pc_self = (const tnet_stun_attr_error_code_t*)pc_self;
- *((uint32_t*)&p_buff_ptr[*p_written]) = (uint32_t)tnet_htonl(((_pc_self->u_class & 0x07) << 8) | _pc_self->u_number);
- if (_pc_self->p_reason_phrase) {
- memcpy(&p_buff_ptr[*p_written + 4], _pc_self->p_reason_phrase, tsk_strlen(_pc_self->p_reason_phrase));
- }
- *p_written += 4 + tsk_strlen(_pc_self->p_reason_phrase);
- if (with_padding) {
- ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
- }
- *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
- return 0;
- }
- default: {
- TSK_DEBUG_ERROR("Attribute type=%d is unknown.", pc_self->hdr.e_type);
- return -2;
- }
- }
+ tsk_size_t n_min_req_size;
+ int ret;
+ if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if ((ret = _tnet_stun_attr_get_size_in_octetunits(pc_self, with_padding, &n_min_req_size))) {
+ return ret;
+ }
+ if (n_min_req_size > n_buff_size) {
+ TSK_DEBUG_ERROR("Buffer too short %u<%u", (unsigned)n_buff_size, (unsigned)n_min_req_size);
+ return -2;
+ }
+
+ *((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->hdr.e_type);
+ // *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)pc_self->hdr.u_length);
+ *p_written = kStunAttrHdrSizeInOctets;
+
+ switch (pc_self->hdr.e_type) {
+ case tnet_stun_attr_type_mapped_address:
+ case tnet_stun_attr_type_alternate_server:
+ case tnet_stun_attr_type_xor_mapped_address:
+ case tnet_stun_attr_type_xor_peer_address:
+ case tnet_stun_attr_type_xor_relayed_address: {
+ tsk_size_t u_addr_size;
+ extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
+ const tnet_stun_attr_address_t* _pc_self = (const tnet_stun_attr_address_t*)pc_self;
+ tsk_bool_t b_xor = IS_ADDRESS_XOR(pc_self->hdr.e_type);
+ if (pc_self->__def__ != tnet_stun_attr_address_def_t) {
+ TSK_DEBUG_ERROR("Invalid base type");
+ return -2;
+ }
+ p_buff_ptr[*p_written] = 0x00; // Reserved
+ p_buff_ptr[*p_written + 1] = _pc_self->e_family;
+ u_addr_size = (_pc_self->e_family == tnet_stun_address_family_ipv6 ? 16 : 4);
+ if (b_xor) {
+ tsk_size_t u;
+ *((uint16_t*)&p_buff_ptr[*p_written + 2]) = tnet_htons(_pc_self->u_port ^ kStunMagicCookieShort);
+ *((uint32_t*)&p_buff_ptr[*p_written + 4]) = (uint32_t)tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[0])) ^ kStunMagicCookieLong);
+ for (u = 4; u < u_addr_size; u += 4) {
+ if (pc_transac_id) {
+ *((uint32_t*)&p_buff_ptr[*p_written + 4 + u]) = (uint32_t)tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[u])) ^ tnet_ntohl(*((uint32_t*)(*pc_transac_id + u - 4))));
+ }
+ else {
+ *((uint32_t*)&p_buff_ptr[*p_written + 4 + u]) = (uint32_t)tnet_htonl(tnet_ntohl(*((uint32_t*)&_pc_self->address[u])) ^ 0);
+ }
+ }
+ }
+ else {
+ *((uint16_t*)&p_buff_ptr[*p_written + 2]) = tnet_htons(_pc_self->u_port);
+ memcpy(&p_buff_ptr[*p_written + 4], _pc_self->address, u_addr_size);
+ }
+
+ *p_written += 4 + u_addr_size;
+ *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
+ if (with_padding) {
+ ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
+ }
+ return 0;
+ }
+
+ case tnet_stun_attr_type_data:
+ case tnet_stun_attr_type_unknown_attrs:
+ case tnet_stun_attr_type_dont_fragment:
+ case tnet_stun_attr_type_software:
+ case tnet_stun_attr_type_nonce:
+ case tnet_stun_attr_type_realm:
+ case tnet_stun_attr_type_username:
+ case tnet_stun_attr_type_password:
+ case tnet_stun_attr_type_channel_number:
+ case tnet_stun_attr_type_message_integrity:
+ case tnet_stun_attr_type_fingerprint:
+ case tnet_stun_attr_type_lifetime:
+ case tnet_stun_attr_type_requested_transport:
+ case tnet_stun_attr_type_ice_use_candidate:
+ case tnet_stun_attr_type_ice_priority:
+ case tnet_stun_attr_type_ice_controlled:
+ case tnet_stun_attr_type_ice_controlling:
+ case tnet_stun_attr_type_connection_id: {
+ extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
+ const tnet_stun_attr_vdata_t* _pc_self = (const tnet_stun_attr_vdata_t*)pc_self;
+ if (pc_self->__def__ != tnet_stun_attr_vdata_def_t) {
+ TSK_DEBUG_ERROR("Invalid base type");
+ return -2;
+ }
+ if (_pc_self->p_data_ptr && _pc_self->u_data_size) {
+ if (IS_VDATA_UINT16(pc_self->hdr.e_type) && _pc_self->u_data_size == 2) {
+ *((uint16_t*)&p_buff_ptr[*p_written]) = tnet_htons_2(&_pc_self->p_data_ptr[0]);
+ }
+ else if (IS_VDATA_UINT32(pc_self->hdr.e_type) && _pc_self->u_data_size == 4) {
+ *((uint32_t*)&p_buff_ptr[*p_written]) = (uint32_t)tnet_htonl_2(&_pc_self->p_data_ptr[0]);
+ }
+ else if (IS_VDATA_UINT64(pc_self->hdr.e_type) && _pc_self->u_data_size == 8) {
+ *((uint32_t*)&p_buff_ptr[*p_written]) = (uint32_t)tnet_htonl_2(&_pc_self->p_data_ptr[0]);
+ *((uint32_t*)&p_buff_ptr[*p_written + 4]) = (uint32_t)tnet_htonl_2(&_pc_self->p_data_ptr[4]);
+ }
+ else if (pc_self->hdr.e_type == tnet_stun_attr_type_unknown_attrs && _pc_self->u_data_size && !(_pc_self->u_data_size & 1)) {
+ uint16_t u;
+ for (u = 0; u < _pc_self->u_data_size; u += 2) {
+ *((uint16_t*)&p_buff_ptr[*p_written + u]) = tnet_htons_2(&_pc_self->p_data_ptr[u]);
+ }
+ }
+ else {
+ memcpy(&p_buff_ptr[*p_written], _pc_self->p_data_ptr, _pc_self->u_data_size);
+ }
+ *p_written += _pc_self->u_data_size;
+ }
+ if (with_padding) {
+ ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
+ }
+ *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
+ return 0;
+ }
+ case tnet_stun_attr_type_error_code: {
+ const tnet_stun_attr_error_code_t* _pc_self = (const tnet_stun_attr_error_code_t*)pc_self;
+ *((uint32_t*)&p_buff_ptr[*p_written]) = (uint32_t)tnet_htonl(((_pc_self->u_class & 0x07) << 8) | _pc_self->u_number);
+ if (_pc_self->p_reason_phrase) {
+ memcpy(&p_buff_ptr[*p_written + 4], _pc_self->p_reason_phrase, tsk_strlen(_pc_self->p_reason_phrase));
+ }
+ *p_written += 4 + tsk_strlen(_pc_self->p_reason_phrase);
+ if (with_padding) {
+ ALIGN_ON_32BITS_AND_SET_PADDING_ZEROS(&p_buff_ptr[*p_written], *p_written);
+ }
+ *((uint16_t*)&p_buff_ptr[2]) = tnet_htons((unsigned short)*p_written - kStunAttrHdrSizeInOctets);
+ return 0;
+ }
+ default: {
+ TSK_DEBUG_ERROR("Attribute type=%d is unknown.", pc_self->hdr.e_type);
+ return -2;
+ }
+ }
}
int tnet_stun_attr_init(tnet_stun_attr_t* p_self, tnet_stun_attr_type_t e_type, uint16_t u_length)
{
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- p_self->hdr.e_type = e_type;
- p_self->hdr.u_length = u_length;
- return 0;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ p_self->hdr.e_type = e_type;
+ p_self->hdr.u_length = u_length;
+ return 0;
}
int tnet_stun_attr_get_size_in_octetunits_without_padding(const tnet_stun_attr_t* pc_self, tsk_size_t* p_size)
{
- return _tnet_stun_attr_get_size_in_octetunits(pc_self, kWithoutPadding, p_size);
+ return _tnet_stun_attr_get_size_in_octetunits(pc_self, kWithoutPadding, p_size);
}
int tnet_stun_attr_get_size_in_octetunits_with_padding(const tnet_stun_attr_t* pc_self, tsk_size_t* p_size)
{
- return _tnet_stun_attr_get_size_in_octetunits(pc_self, kWithPadding, p_size);
+ return _tnet_stun_attr_get_size_in_octetunits(pc_self, kWithPadding, p_size);
}
int tnet_stun_attr_write_without_padding(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
{
- return _tnet_stun_attr_write(pc_transac_id, pc_self, p_buff_ptr, n_buff_size, kWithoutPadding, p_written);
+ return _tnet_stun_attr_write(pc_transac_id, pc_self, p_buff_ptr, n_buff_size, kWithoutPadding, p_written);
}
int tnet_stun_attr_write_with_padding(const tnet_stun_transac_id_t* pc_transac_id, const tnet_stun_attr_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
{
- return _tnet_stun_attr_write(pc_transac_id, pc_self, p_buff_ptr, n_buff_size, kWithPadding, p_written);
+ return _tnet_stun_attr_write(pc_transac_id, pc_self, p_buff_ptr, n_buff_size, kWithPadding, p_written);
}
int tnet_stun_attr_read(const tnet_stun_transac_id_t* pc_transac_id, const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_consumed_octets, tnet_stun_attr_t** pp_attr)
{
- tnet_stun_attr_type_t Type;
- uint16_t Length, PadLength;
- int ret = -1;
- static const void* kNullBuffPtr = tsk_null;
- if (!pc_buff_ptr || !n_buff_size || !pp_attr || !p_consumed_octets) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (n_buff_size < kStunAttrHdrSizeInOctets) {
- TSK_DEBUG_ERROR("Buffer too short(%u)", (unsigned)n_buff_size);
- return -2;
- }
-
- Type = tnet_ntohs_2(&pc_buff_ptr[0]);
- Length = tnet_ntohs_2(&pc_buff_ptr[2]);
- if (Length > n_buff_size) {
- TSK_DEBUG_ERROR("Buffer too short(%u). Length=%u", (unsigned)n_buff_size, (unsigned)Length);
- return -3;
- }
-
- PadLength = (Length & 0x03) ? (4 - (Length & 0x03)) : 0;
-
- *pp_attr = tsk_null;
- *p_consumed_octets = kStunAttrHdrSizeInOctets + Length + PadLength;
-
- switch (Type) {
- case tnet_stun_attr_type_mapped_address:
- case tnet_stun_attr_type_alternate_server:
- case tnet_stun_attr_type_xor_mapped_address:
- case tnet_stun_attr_type_xor_peer_address:
- case tnet_stun_attr_type_xor_relayed_address: {
- // First 8bits must be ignored
- tnet_stun_address_family_t e_family = pc_buff_ptr[5];
- uint16_t u_port = tnet_ntohs_2(&pc_buff_ptr[6]);
- tnet_stun_attr_address_t* p_attr;
- tsk_bool_t b_xor = IS_ADDRESS_XOR(Type);
- uint16_t u, u_addr_size = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4;
-
- if (b_xor) {
- u_port ^= kStunMagicCookieShort;
- }
- if ((ret = tnet_stun_attr_address_create(Type, e_family, u_port, (const tnet_stun_addr_t*)kNullBuffPtr, &p_attr))) {
- return ret;
- }
- if (b_xor) {
- *((uint32_t*)&p_attr->address[0]) = (uint32_t)tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8]) ^ kStunMagicCookieLong);
- for (u = 4; u < u_addr_size; u += 4) {
- if (pc_transac_id) {
- *((uint32_t*)&p_attr->address[u]) = (uint32_t)tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8 + u]) ^ tnet_ntohl_2(((uint32_t*)(*pc_transac_id + u - 4))));
- }
- else {
- *((uint32_t*)&p_attr->address[u]) = (uint32_t)tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8 + u]) ^ 0);
- }
- }
- }
- else {
- memcpy(p_attr->address, &pc_buff_ptr[8], u_addr_size);
- }
- *pp_attr = TNET_STUN_ATTR(p_attr);
- break;
- }
-
- case tnet_stun_attr_type_error_code: {
- // First 21bits must be ignored
- uint8_t Class = pc_buff_ptr[6] & 0x07;
- uint8_t Number = pc_buff_ptr[7] & 0xff;
- tnet_stun_attr_error_code_t* p_attr;
- if ((ret = tnet_stun_attr_error_code_create(Class, Number, &pc_buff_ptr[8], (Length - 4), &p_attr))) {
- return ret;
- }
- *pp_attr = TNET_STUN_ATTR(p_attr);
- break;
- }
-
- case tnet_stun_attr_type_data:
- case tnet_stun_attr_type_unknown_attrs:
- case tnet_stun_attr_type_dont_fragment:
- case tnet_stun_attr_type_software:
- case tnet_stun_attr_type_nonce:
- case tnet_stun_attr_type_realm:
- case tnet_stun_attr_type_username:
- case tnet_stun_attr_type_password:
- case tnet_stun_attr_type_channel_number:
- case tnet_stun_attr_type_message_integrity:
- case tnet_stun_attr_type_fingerprint:
- case tnet_stun_attr_type_lifetime:
- case tnet_stun_attr_type_requested_transport:
- case tnet_stun_attr_type_ice_use_candidate:
- case tnet_stun_attr_type_ice_priority:
- case tnet_stun_attr_type_ice_controlled:
- case tnet_stun_attr_type_ice_controlling:
- case tnet_stun_attr_type_connection_id:
- default: {
- tnet_stun_attr_vdata_t* p_attr;
- if (IS_VDATA_UINT16(Type) && Length == 2) {
- uint16_t u16 = tnet_ntohs_2(&pc_buff_ptr[4]);
- if ((ret = tnet_stun_attr_vdata_create(Type, (uint8_t*)&u16, 2, &p_attr))) {
- return ret;
- }
- }
- else if (IS_VDATA_UINT32(Type) && Length == 4) {
- uint32_t u32 = (uint32_t)tnet_ntohl_2(&pc_buff_ptr[4]);
- if ((ret = tnet_stun_attr_vdata_create(Type, (uint8_t*)&u32, 4, &p_attr))) {
- return ret;
- }
- }
- else if (IS_VDATA_UINT64(Type) && Length == 8) {
- uint64_t u64 = ((uint64_t)tnet_ntohl_2(&pc_buff_ptr[4])) << 32;
- u64 |= tnet_ntohl_2(&pc_buff_ptr[8]);
- if ((ret = tnet_stun_attr_vdata_create(Type, (uint8_t*)&u64, 8, &p_attr))) {
- return ret;
- }
- }
- else if (Type == tnet_stun_attr_type_unknown_attrs && Length && !(Length & 1)) {
- uint16_t u;
- uint8_t *_p_data_ptr = tsk_malloc(Length);
- if (!_p_data_ptr) {
- TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", Length);
- return -4;
- }
- memcpy(_p_data_ptr, &pc_buff_ptr[4], Length);
- for (u = 0; u < Length; u += 2) {
- *((uint16_t*)&_p_data_ptr[u]) = tnet_htons_2(&_p_data_ptr[u]);
- }
- if ((ret = tnet_stun_attr_vdata_create(Type, _p_data_ptr, Length, &p_attr))) {
- TSK_FREE(_p_data_ptr);
- return ret;
- }
- TSK_FREE(_p_data_ptr);
- }
- else {
- if ((ret = tnet_stun_attr_vdata_create(Type, &pc_buff_ptr[4], Length, &p_attr))) {
- return ret;
- }
- }
- *pp_attr = TNET_STUN_ATTR(p_attr);
- break;
- }
- }
- return ret;
+ tnet_stun_attr_type_t Type;
+ uint16_t Length, PadLength;
+ int ret = -1;
+ static const void* kNullBuffPtr = tsk_null;
+ if (!pc_buff_ptr || !n_buff_size || !pp_attr || !p_consumed_octets) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (n_buff_size < kStunAttrHdrSizeInOctets) {
+ TSK_DEBUG_ERROR("Buffer too short(%u)", (unsigned)n_buff_size);
+ return -2;
+ }
+
+ Type = tnet_ntohs_2(&pc_buff_ptr[0]);
+ Length = tnet_ntohs_2(&pc_buff_ptr[2]);
+ if (Length > n_buff_size) {
+ TSK_DEBUG_ERROR("Buffer too short(%u). Length=%u", (unsigned)n_buff_size, (unsigned)Length);
+ return -3;
+ }
+
+ PadLength = (Length & 0x03) ? (4 - (Length & 0x03)) : 0;
+
+ *pp_attr = tsk_null;
+ *p_consumed_octets = kStunAttrHdrSizeInOctets + Length + PadLength;
+
+ switch (Type) {
+ case tnet_stun_attr_type_mapped_address:
+ case tnet_stun_attr_type_alternate_server:
+ case tnet_stun_attr_type_xor_mapped_address:
+ case tnet_stun_attr_type_xor_peer_address:
+ case tnet_stun_attr_type_xor_relayed_address: {
+ // First 8bits must be ignored
+ tnet_stun_address_family_t e_family = pc_buff_ptr[5];
+ uint16_t u_port = tnet_ntohs_2(&pc_buff_ptr[6]);
+ tnet_stun_attr_address_t* p_attr;
+ tsk_bool_t b_xor = IS_ADDRESS_XOR(Type);
+ uint16_t u, u_addr_size = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4;
+
+ if (b_xor) {
+ u_port ^= kStunMagicCookieShort;
+ }
+ if ((ret = tnet_stun_attr_address_create(Type, e_family, u_port, (const tnet_stun_addr_t*)kNullBuffPtr, &p_attr))) {
+ return ret;
+ }
+ if (b_xor) {
+ *((uint32_t*)&p_attr->address[0]) = (uint32_t)tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8]) ^ kStunMagicCookieLong);
+ for (u = 4; u < u_addr_size; u += 4) {
+ if (pc_transac_id) {
+ *((uint32_t*)&p_attr->address[u]) = (uint32_t)tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8 + u]) ^ tnet_ntohl_2(((uint32_t*)(*pc_transac_id + u - 4))));
+ }
+ else {
+ *((uint32_t*)&p_attr->address[u]) = (uint32_t)tnet_htonl(tnet_ntohl_2(&pc_buff_ptr[8 + u]) ^ 0);
+ }
+ }
+ }
+ else {
+ memcpy(p_attr->address, &pc_buff_ptr[8], u_addr_size);
+ }
+ *pp_attr = TNET_STUN_ATTR(p_attr);
+ break;
+ }
+
+ case tnet_stun_attr_type_error_code: {
+ // First 21bits must be ignored
+ uint8_t Class = pc_buff_ptr[6] & 0x07;
+ uint8_t Number = pc_buff_ptr[7] & 0xff;
+ tnet_stun_attr_error_code_t* p_attr;
+ if ((ret = tnet_stun_attr_error_code_create(Class, Number, &pc_buff_ptr[8], (Length - 4), &p_attr))) {
+ return ret;
+ }
+ *pp_attr = TNET_STUN_ATTR(p_attr);
+ break;
+ }
+
+ case tnet_stun_attr_type_data:
+ case tnet_stun_attr_type_unknown_attrs:
+ case tnet_stun_attr_type_dont_fragment:
+ case tnet_stun_attr_type_software:
+ case tnet_stun_attr_type_nonce:
+ case tnet_stun_attr_type_realm:
+ case tnet_stun_attr_type_username:
+ case tnet_stun_attr_type_password:
+ case tnet_stun_attr_type_channel_number:
+ case tnet_stun_attr_type_message_integrity:
+ case tnet_stun_attr_type_fingerprint:
+ case tnet_stun_attr_type_lifetime:
+ case tnet_stun_attr_type_requested_transport:
+ case tnet_stun_attr_type_ice_use_candidate:
+ case tnet_stun_attr_type_ice_priority:
+ case tnet_stun_attr_type_ice_controlled:
+ case tnet_stun_attr_type_ice_controlling:
+ case tnet_stun_attr_type_connection_id:
+ default: {
+ tnet_stun_attr_vdata_t* p_attr;
+ if (IS_VDATA_UINT16(Type) && Length == 2) {
+ uint16_t u16 = tnet_ntohs_2(&pc_buff_ptr[4]);
+ if ((ret = tnet_stun_attr_vdata_create(Type, (uint8_t*)&u16, 2, &p_attr))) {
+ return ret;
+ }
+ }
+ else if (IS_VDATA_UINT32(Type) && Length == 4) {
+ uint32_t u32 = (uint32_t)tnet_ntohl_2(&pc_buff_ptr[4]);
+ if ((ret = tnet_stun_attr_vdata_create(Type, (uint8_t*)&u32, 4, &p_attr))) {
+ return ret;
+ }
+ }
+ else if (IS_VDATA_UINT64(Type) && Length == 8) {
+ uint64_t u64 = ((uint64_t)tnet_ntohl_2(&pc_buff_ptr[4])) << 32;
+ u64 |= tnet_ntohl_2(&pc_buff_ptr[8]);
+ if ((ret = tnet_stun_attr_vdata_create(Type, (uint8_t*)&u64, 8, &p_attr))) {
+ return ret;
+ }
+ }
+ else if (Type == tnet_stun_attr_type_unknown_attrs && Length && !(Length & 1)) {
+ uint16_t u;
+ uint8_t *_p_data_ptr = tsk_malloc(Length);
+ if (!_p_data_ptr) {
+ TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", Length);
+ return -4;
+ }
+ memcpy(_p_data_ptr, &pc_buff_ptr[4], Length);
+ for (u = 0; u < Length; u += 2) {
+ *((uint16_t*)&_p_data_ptr[u]) = tnet_htons_2(&_p_data_ptr[u]);
+ }
+ if ((ret = tnet_stun_attr_vdata_create(Type, _p_data_ptr, Length, &p_attr))) {
+ TSK_FREE(_p_data_ptr);
+ return ret;
+ }
+ TSK_FREE(_p_data_ptr);
+ }
+ else {
+ if ((ret = tnet_stun_attr_vdata_create(Type, &pc_buff_ptr[4], Length, &p_attr))) {
+ return ret;
+ }
+ }
+ *pp_attr = TNET_STUN_ATTR(p_attr);
+ break;
+ }
+ }
+ return ret;
}
// ============== VDATA (USERNAME, MESSAGE-INTEGRITY, ...) ================ //
int tnet_stun_attr_vdata_create(tnet_stun_attr_type_t e_type, const uint8_t* pc_data_ptr, uint16_t u_data_size, tnet_stun_attr_vdata_t** pp_attr)
{
- int ret = -1;
- uint16_t u_length = pc_data_ptr ? u_data_size : 0;
- tnet_stun_attr_vdata_t* p_attr = tsk_null;
- extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
- if (!pp_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if (!(p_attr = tsk_object_new(tnet_stun_attr_vdata_def_t))) {
- ret = -2;
- goto bail;
- }
- if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), e_type, u_length))) {
- goto bail;
- }
- if (u_length) {
- if (!(p_attr->p_data_ptr = tsk_malloc(u_length + 1))) {
- ret = -3;
- goto bail;
- }
- memcpy(p_attr->p_data_ptr, pc_data_ptr, u_length);
- p_attr->u_data_size = u_length;
- p_attr->p_data_ptr[u_length] = '\0';
- }
- *pp_attr = p_attr;
+ int ret = -1;
+ uint16_t u_length = pc_data_ptr ? u_data_size : 0;
+ tnet_stun_attr_vdata_t* p_attr = tsk_null;
+ extern const tsk_object_def_t *tnet_stun_attr_vdata_def_t;
+ if (!pp_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if (!(p_attr = tsk_object_new(tnet_stun_attr_vdata_def_t))) {
+ ret = -2;
+ goto bail;
+ }
+ if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), e_type, u_length))) {
+ goto bail;
+ }
+ if (u_length) {
+ if (!(p_attr->p_data_ptr = tsk_malloc(u_length + 1))) {
+ ret = -3;
+ goto bail;
+ }
+ memcpy(p_attr->p_data_ptr, pc_data_ptr, u_length);
+ p_attr->u_data_size = u_length;
+ p_attr->p_data_ptr[u_length] = '\0';
+ }
+ *pp_attr = p_attr;
bail:
- if (ret) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- }
- return ret;
+ if (ret) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ }
+ return ret;
}
int tnet_stun_attr_vdata_update(tnet_stun_attr_vdata_t* p_self, const uint8_t* pc_data_ptr, uint16_t u_data_size)
{
- uint16_t _u_data_size = (pc_data_ptr && u_data_size) ? u_data_size : 0;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (_u_data_size) {
- if (!(p_self->p_data_ptr = tsk_realloc(p_self->p_data_ptr, _u_data_size + 1))) {
- p_self->u_data_size = 0;
- ((tnet_stun_attr_t*)p_self)->hdr.u_length = 0;
- return -3;
- }
- memcpy(p_self->p_data_ptr, pc_data_ptr, _u_data_size);
- p_self->p_data_ptr[_u_data_size] = '\0';
- }
- else {
- TSK_FREE(p_self->p_data_ptr);
- }
- p_self->u_data_size = _u_data_size;
- ((tnet_stun_attr_t*)p_self)->hdr.u_length = p_self->u_data_size;
- return 0;
+ uint16_t _u_data_size = (pc_data_ptr && u_data_size) ? u_data_size : 0;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (_u_data_size) {
+ if (!(p_self->p_data_ptr = tsk_realloc(p_self->p_data_ptr, _u_data_size + 1))) {
+ p_self->u_data_size = 0;
+ ((tnet_stun_attr_t*)p_self)->hdr.u_length = 0;
+ return -3;
+ }
+ memcpy(p_self->p_data_ptr, pc_data_ptr, _u_data_size);
+ p_self->p_data_ptr[_u_data_size] = '\0';
+ }
+ else {
+ TSK_FREE(p_self->p_data_ptr);
+ }
+ p_self->u_data_size = _u_data_size;
+ ((tnet_stun_attr_t*)p_self)->hdr.u_length = p_self->u_data_size;
+ return 0;
}
static tsk_object_t* tnet_stun_attr_vdata_ctor(tsk_object_t * self, va_list * app)
{
- tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
- if (p_vdata) {
- }
- return self;
+ tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
+ if (p_vdata) {
+ }
+ return self;
}
static tsk_object_t* tnet_stun_attr_vdata_dtor(tsk_object_t * self)
{
- tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
- if (p_vdata) {
+ tnet_stun_attr_vdata_t *p_vdata = (tnet_stun_attr_vdata_t *)self;
+ if (p_vdata) {
#if PRINT_DESTROYED_MSG
- TSK_DEBUG_INFO("*** STUN Attribute(VDATA) destroyed ***");
+ TSK_DEBUG_INFO("*** STUN Attribute(VDATA) destroyed ***");
#endif
- TSK_FREE(p_vdata->p_data_ptr);
- }
- return self;
+ TSK_FREE(p_vdata->p_data_ptr);
+ }
+ return self;
}
static const tsk_object_def_t tnet_stun_attr_vdata_def_s = {
- sizeof(tnet_stun_attr_vdata_t),
- tnet_stun_attr_vdata_ctor,
- tnet_stun_attr_vdata_dtor,
- _tnet_stun_attr_cmp,
+ sizeof(tnet_stun_attr_vdata_t),
+ tnet_stun_attr_vdata_ctor,
+ tnet_stun_attr_vdata_dtor,
+ _tnet_stun_attr_cmp,
};
const tsk_object_def_t *tnet_stun_attr_vdata_def_t = &tnet_stun_attr_vdata_def_s;
@@ -533,57 +533,57 @@ const tsk_object_def_t *tnet_stun_attr_vdata_def_t = &tnet_stun_attr_vdata_def_s
// ============== ADDRESS ================ //
int tnet_stun_attr_address_create(tnet_stun_attr_type_t e_type, tnet_stun_address_family_t e_family, uint16_t u_port, const tnet_stun_addr_t* pc_addr, tnet_stun_attr_address_t** pp_attr)
{
- int ret = -1;
- extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
- tnet_stun_attr_address_t* p_attr = tsk_null;
- uint16_t u_length = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4;
- if (!pp_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (!(p_attr = tsk_object_new(tnet_stun_attr_address_def_t))) {
- ret = -2;
- goto bail;
- }
- if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), e_type, u_length))) {
- goto bail;
- }
- p_attr->e_family = e_family;
- p_attr->u_port = u_port;
- if (pc_addr) {
- memcpy(p_attr->address, *pc_addr, u_length);
- }
- *pp_attr = p_attr;
+ int ret = -1;
+ extern const tsk_object_def_t *tnet_stun_attr_address_def_t;
+ tnet_stun_attr_address_t* p_attr = tsk_null;
+ uint16_t u_length = (e_family == tnet_stun_address_family_ipv6) ? 16 : 4;
+ if (!pp_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (!(p_attr = tsk_object_new(tnet_stun_attr_address_def_t))) {
+ ret = -2;
+ goto bail;
+ }
+ if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), e_type, u_length))) {
+ goto bail;
+ }
+ p_attr->e_family = e_family;
+ p_attr->u_port = u_port;
+ if (pc_addr) {
+ memcpy(p_attr->address, *pc_addr, u_length);
+ }
+ *pp_attr = p_attr;
bail:
- if (ret) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- }
- return ret;
+ if (ret) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ }
+ return ret;
}
static tsk_object_t* tnet_stun_attr_address_ctor(tsk_object_t * self, va_list * app)
{
- tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
- if (p_addr) {
- }
- return self;
+ tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
+ if (p_addr) {
+ }
+ return self;
}
static tsk_object_t* tnet_stun_attr_address_dtor(tsk_object_t * self)
{
- tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
- if (p_addr) {
+ tnet_stun_attr_address_t *p_addr = (tnet_stun_attr_address_t *)self;
+ if (p_addr) {
#if PRINT_DESTROYED_MSG
- TSK_DEBUG_INFO("*** STUN Attribute(ADDRESS) destroyed ***");
+ TSK_DEBUG_INFO("*** STUN Attribute(ADDRESS) destroyed ***");
#endif
- }
- return self;
+ }
+ return self;
}
static const tsk_object_def_t tnet_stun_attr_address_def_s = {
- sizeof(tnet_stun_attr_address_t),
- tnet_stun_attr_address_ctor,
- tnet_stun_attr_address_dtor,
- _tnet_stun_attr_cmp,
+ sizeof(tnet_stun_attr_address_t),
+ tnet_stun_attr_address_ctor,
+ tnet_stun_attr_address_dtor,
+ _tnet_stun_attr_cmp,
};
const tsk_object_def_t *tnet_stun_attr_address_def_t = &tnet_stun_attr_address_def_s;
@@ -592,60 +592,60 @@ const tsk_object_def_t *tnet_stun_attr_address_def_t = &tnet_stun_attr_address_d
// ================ 15.6. ERROR-CODE ========== //
int tnet_stun_attr_error_code_create(uint8_t u_class, uint8_t u_number, const void* pc_reason_phrase, uint16_t u_reason_phrase, struct tnet_stun_attr_error_code_s** pp_attr)
{
- int ret = -1;
- extern const tsk_object_def_t *tnet_stun_attr_error_code_def_t;
- tnet_stun_attr_error_code_t* p_attr = tsk_null;
- uint16_t u_length = (uint16_t)(4 + tsk_strlen(pc_reason_phrase));
- if (!pp_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (!(p_attr = tsk_object_new(tnet_stun_attr_error_code_def_t))) {
- ret = -2;
- goto bail;
- }
- if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), tnet_stun_attr_type_error_code, u_length))) {
- goto bail;
- }
- p_attr->u_class = u_class;
- p_attr->u_number = u_number;
- if (pc_reason_phrase && u_reason_phrase) {
- if (!(p_attr->p_reason_phrase = tsk_strndup(pc_reason_phrase, u_reason_phrase))) {
- ret = -3;
- goto bail;
- }
- }
- *pp_attr = p_attr;
+ int ret = -1;
+ extern const tsk_object_def_t *tnet_stun_attr_error_code_def_t;
+ tnet_stun_attr_error_code_t* p_attr = tsk_null;
+ uint16_t u_length = (uint16_t)(4 + tsk_strlen(pc_reason_phrase));
+ if (!pp_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (!(p_attr = tsk_object_new(tnet_stun_attr_error_code_def_t))) {
+ ret = -2;
+ goto bail;
+ }
+ if ((ret = tnet_stun_attr_init(TNET_STUN_ATTR(p_attr), tnet_stun_attr_type_error_code, u_length))) {
+ goto bail;
+ }
+ p_attr->u_class = u_class;
+ p_attr->u_number = u_number;
+ if (pc_reason_phrase && u_reason_phrase) {
+ if (!(p_attr->p_reason_phrase = tsk_strndup(pc_reason_phrase, u_reason_phrase))) {
+ ret = -3;
+ goto bail;
+ }
+ }
+ *pp_attr = p_attr;
bail:
- if (ret) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- }
- return ret;
+ if (ret) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ }
+ return ret;
}
static tsk_object_t* tnet_stun_attr_error_code_ctor(tsk_object_t * self, va_list * app)
{
- tnet_stun_attr_error_code_t *p_ec = (tnet_stun_attr_error_code_t *)self;
- if (p_ec) {
- }
- return self;
+ tnet_stun_attr_error_code_t *p_ec = (tnet_stun_attr_error_code_t *)self;
+ if (p_ec) {
+ }
+ return self;
}
static tsk_object_t* tnet_stun_attr_error_code_dtor(tsk_object_t * self)
{
- tnet_stun_attr_error_code_t *p_ec = (tnet_stun_attr_error_code_t *)self;
- if (p_ec) {
+ tnet_stun_attr_error_code_t *p_ec = (tnet_stun_attr_error_code_t *)self;
+ if (p_ec) {
#if PRINT_DESTROYED_MSG
- TSK_DEBUG_INFO("*** STUN Attribute(ERROR-CODE) destroyed ***");
+ TSK_DEBUG_INFO("*** STUN Attribute(ERROR-CODE) destroyed ***");
#endif
- TSK_FREE(p_ec->p_reason_phrase);
- }
- return self;
+ TSK_FREE(p_ec->p_reason_phrase);
+ }
+ return self;
}
static const tsk_object_def_t tnet_stun_attr_error_code_def_s = {
- sizeof(tnet_stun_attr_error_code_t),
- tnet_stun_attr_error_code_ctor,
- tnet_stun_attr_error_code_dtor,
- _tnet_stun_attr_cmp,
+ sizeof(tnet_stun_attr_error_code_t),
+ tnet_stun_attr_error_code_ctor,
+ tnet_stun_attr_error_code_dtor,
+ _tnet_stun_attr_cmp,
};
const tsk_object_def_t *tnet_stun_attr_error_code_def_t = &tnet_stun_attr_error_code_def_s;
diff --git a/tinyNET/src/stun/tnet_stun_pkt.c b/tinyNET/src/stun/tnet_stun_pkt.c
index e4d559d..a996897 100755
--- a/tinyNET/src/stun/tnet_stun_pkt.c
+++ b/tinyNET/src/stun/tnet_stun_pkt.c
@@ -36,716 +36,717 @@
int tnet_stun_pkt_create(tnet_stun_pkt_type_t e_type, uint16_t u_length, const tnet_stun_transac_id_t* pc_transac_id, tnet_stun_pkt_t** pp_attr)
{
- extern const tsk_object_def_t *tnet_stun_pkt_def_t;
- if (!pp_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (!(*pp_attr = tsk_object_new(tnet_stun_pkt_def_t))) {
- TSK_DEBUG_ERROR("Failed to create STUN pkt object");
- return -2;
- }
- if (!((*pp_attr)->p_list_attrs = tsk_list_create())) {
- TSK_OBJECT_SAFE_FREE(*pp_attr);
- return -3;
- }
- if (pc_transac_id) {
- memcpy((*pp_attr)->transac_id, *pc_transac_id, sizeof(tnet_stun_transac_id_t));
- }
- else {
- tnet_stun_utils_transac_id_rand(&(*pp_attr)->transac_id);
- }
- (*pp_attr)->e_type = e_type;
- (*pp_attr)->u_length = u_length;
- return 0;
+ extern const tsk_object_def_t *tnet_stun_pkt_def_t;
+ if (!pp_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (!(*pp_attr = tsk_object_new(tnet_stun_pkt_def_t))) {
+ TSK_DEBUG_ERROR("Failed to create STUN pkt object");
+ return -2;
+ }
+ if (!((*pp_attr)->p_list_attrs = tsk_list_create())) {
+ TSK_OBJECT_SAFE_FREE(*pp_attr);
+ return -3;
+ }
+ if (pc_transac_id) {
+ memcpy((*pp_attr)->transac_id, *pc_transac_id, sizeof(tnet_stun_transac_id_t));
+ }
+ else {
+ tnet_stun_utils_transac_id_rand(&(*pp_attr)->transac_id);
+ }
+ (*pp_attr)->e_type = e_type;
+ (*pp_attr)->u_length = u_length;
+ return 0;
}
int tnet_stun_pkt_attr_add(tnet_stun_pkt_t* p_self, tnet_stun_attr_t** pp_attr)
{
- if (!p_self || !pp_attr || !*pp_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_list_push_back_data(p_self->p_list_attrs, (void**)pp_attr);
- return 0;
+ if (!p_self || !pp_attr || !*pp_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_list_push_back_data(p_self->p_list_attrs, (void**)pp_attr);
+ return 0;
}
int tnet_stun_pkt_attrs_add(tnet_stun_pkt_t* p_self, ...)
{
- va_list ap;
- int ret = 0;
- tnet_stun_pkt_attr_add_t e_add_attr;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- va_start(ap, p_self);
-
- while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
- switch (e_add_attr) {
- case tnet_stun_pkt_attr_add_vdata: {
- // (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
- enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
- const uint8_t* P_DATA_PTR = va_arg(ap, const uint8_t*);
- uint16_t U_DATA_SIZE = tsk_va_arg_u16(ap);
- tnet_stun_attr_vdata_t *p_attr;
- if ((ret = tnet_stun_attr_vdata_create(E_TYPE, P_DATA_PTR, U_DATA_SIZE, &p_attr))) {
- goto bail;
- }
- if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- goto bail;
- }
- break;
- }
- case tnet_stun_pkt_attr_add_address: {
- // (enum tnet_stun_attr_type_e)(E_TYPE), (enum tnet_stun_address_family_e)(E_FAMILY), (uint16_t)(U_PORT), (const tnet_stun_addr_t*)PC_ADDR_PTR
- enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
- enum tnet_stun_address_family_e E_FAMILY = va_arg(ap, enum tnet_stun_address_family_e);
- uint16_t U_PORT = tsk_va_arg_u16(ap);
- const tnet_stun_addr_t* PC_ADDR_PTR = va_arg(ap, const tnet_stun_addr_t*);
- tnet_stun_attr_address_t *p_attr;
- if ((ret = tnet_stun_attr_address_create(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR, &p_attr))) {
- goto bail;
- }
- if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- goto bail;
- }
- break;
- }
- case tnet_stun_pkt_attr_add_error_code: {
- // (uint8_t)(U8_CLASS), (uint8_t)(U8_NUMBER), (const char*)(PC_REASON_STR)
- uint8_t U8_CLASS = tsk_va_arg_u8(ap);
- uint8_t U8_NUMBER = tsk_va_arg_u8(ap);
- const char* PC_REASON_STR = va_arg(ap, const char*);
- tnet_stun_attr_error_code_t *p_attr;
- if ((ret = tnet_stun_attr_error_code_create(U8_CLASS, U8_NUMBER, PC_REASON_STR, (uint16_t)tsk_strlen(PC_REASON_STR), &p_attr))) {
- goto bail;
- }
- if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- goto bail;
- }
- break;
- }
- case tnet_stun_pkt_attr_add_unknown_attrs: {
- // (...)
- tsk_buffer_t* p_buffer = tsk_buffer_create_null();
- tnet_stun_attr_vdata_t *p_attr;
- uint16_t u_16;
- if (!p_buffer) {
- TSK_DEBUG_ERROR("Failed to create buffer");
- ret = -4;
- goto bail;
- }
- while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
- if (e_add_attr != tnet_stun_pkt_attr_add_unknown_attrs_val) {
- TSK_OBJECT_SAFE_FREE(p_buffer);
- TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
- ret = -3;
- goto bail;
- }
- u_16 = tsk_va_arg_u16(ap);
- tsk_buffer_append(p_buffer, &u_16, 2);
- }
- if ((ret = tnet_stun_attr_vdata_create(tnet_stun_attr_type_unknown_attrs, p_buffer->data, (uint16_t)p_buffer->size, &p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_buffer);
- goto bail;
- }
- TSK_OBJECT_SAFE_FREE(p_buffer);
- if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
- TSK_OBJECT_SAFE_FREE(p_attr);
- goto bail;
- }
- break;
- }
- default: {
- TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
- ret = -2;
- goto bail;
- }
- }
- }
+ va_list ap;
+ int ret = 0;
+ tnet_stun_pkt_attr_add_t e_add_attr;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ va_start(ap, p_self);
+
+ while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
+ switch (e_add_attr) {
+ case tnet_stun_pkt_attr_add_vdata: {
+ // (enum tnet_stun_attr_type_e)(E_TYPE), (const uint8_t*)(P_DATA_PTR), (uint16_t)(U_DATA_SIZE)
+ enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
+ const uint8_t* P_DATA_PTR = va_arg(ap, const uint8_t*);
+ uint16_t U_DATA_SIZE = tsk_va_arg_u16(ap);
+ tnet_stun_attr_vdata_t *p_attr;
+ if ((ret = tnet_stun_attr_vdata_create(E_TYPE, P_DATA_PTR, U_DATA_SIZE, &p_attr))) {
+ goto bail;
+ }
+ if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ goto bail;
+ }
+ break;
+ }
+ case tnet_stun_pkt_attr_add_address: {
+ // (enum tnet_stun_attr_type_e)(E_TYPE), (enum tnet_stun_address_family_e)(E_FAMILY), (uint16_t)(U_PORT), (const tnet_stun_addr_t*)PC_ADDR_PTR
+ enum tnet_stun_attr_type_e E_TYPE = va_arg(ap, enum tnet_stun_attr_type_e);
+ enum tnet_stun_address_family_e E_FAMILY = va_arg(ap, enum tnet_stun_address_family_e);
+ uint16_t U_PORT = tsk_va_arg_u16(ap);
+ const tnet_stun_addr_t* PC_ADDR_PTR = va_arg(ap, const tnet_stun_addr_t*);
+ tnet_stun_attr_address_t *p_attr;
+ if ((ret = tnet_stun_attr_address_create(E_TYPE, E_FAMILY, U_PORT, PC_ADDR_PTR, &p_attr))) {
+ goto bail;
+ }
+ if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ goto bail;
+ }
+ break;
+ }
+ case tnet_stun_pkt_attr_add_error_code: {
+ // (uint8_t)(U8_CLASS), (uint8_t)(U8_NUMBER), (const char*)(PC_REASON_STR)
+ uint8_t U8_CLASS = tsk_va_arg_u8(ap);
+ uint8_t U8_NUMBER = tsk_va_arg_u8(ap);
+ const char* PC_REASON_STR = va_arg(ap, const char*);
+ tnet_stun_attr_error_code_t *p_attr;
+ if ((ret = tnet_stun_attr_error_code_create(U8_CLASS, U8_NUMBER, PC_REASON_STR, (uint16_t)tsk_strlen(PC_REASON_STR), &p_attr))) {
+ goto bail;
+ }
+ if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ goto bail;
+ }
+ break;
+ }
+ case tnet_stun_pkt_attr_add_unknown_attrs: {
+ // (...)
+ tsk_buffer_t* p_buffer = tsk_buffer_create_null();
+ tnet_stun_attr_vdata_t *p_attr;
+ uint16_t u_16;
+ if (!p_buffer) {
+ TSK_DEBUG_ERROR("Failed to create buffer");
+ ret = -4;
+ goto bail;
+ }
+ while ((e_add_attr = va_arg(ap, tnet_stun_pkt_attr_add_t)) != tnet_stun_pkt_attr_add_null) {
+ if (e_add_attr != tnet_stun_pkt_attr_add_unknown_attrs_val) {
+ TSK_OBJECT_SAFE_FREE(p_buffer);
+ TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
+ ret = -3;
+ goto bail;
+ }
+ u_16 = tsk_va_arg_u16(ap);
+ tsk_buffer_append(p_buffer, &u_16, 2);
+ }
+ if ((ret = tnet_stun_attr_vdata_create(tnet_stun_attr_type_unknown_attrs, p_buffer->data, (uint16_t)p_buffer->size, &p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_buffer);
+ goto bail;
+ }
+ TSK_OBJECT_SAFE_FREE(p_buffer);
+ if ((ret = tnet_stun_pkt_attr_add(p_self, (tnet_stun_attr_t**)&p_attr))) {
+ TSK_OBJECT_SAFE_FREE(p_attr);
+ goto bail;
+ }
+ break;
+ }
+ default: {
+ TSK_DEBUG_ERROR("Arguments corrupted or invalid.");
+ ret = -2;
+ goto bail;
+ }
+ }
+ }
bail:
- va_end(ap);
- return ret;
+ va_end(ap);
+ return ret;
}
int tnet_stun_pkt_attr_remove(struct tnet_stun_pkt_s* p_self, enum tnet_stun_attr_type_e e_type)
{
- tsk_list_item_t* pc_item;
- tnet_stun_attr_t* pc_attr;
- if (!p_self || !p_self->p_list_attrs) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ tsk_list_item_t* pc_item;
+ tnet_stun_attr_t* pc_attr;
+ if (!p_self || !p_self->p_list_attrs) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
again:
- tsk_list_foreach(pc_item, p_self->p_list_attrs) {
- if ((pc_attr = (tnet_stun_attr_t*)pc_item->data)) {
- if (pc_attr->hdr.e_type == e_type) {
- tsk_list_remove_item(p_self->p_list_attrs, pc_item);
- goto again;
- }
- }
- }
- return 0;
+ tsk_list_foreach(pc_item, p_self->p_list_attrs) {
+ if ((pc_attr = (tnet_stun_attr_t*)pc_item->data)) {
+ if (pc_attr->hdr.e_type == e_type) {
+ tsk_list_remove_item(p_self->p_list_attrs, pc_item);
+ goto again;
+ }
+ }
+ }
+ return 0;
}
int tnet_stun_pkt_attr_find(const tnet_stun_pkt_t* pc_self, tnet_stun_attr_type_t e_type, tsk_size_t u_index, const tnet_stun_attr_t** ppc_attr)
{
- const tsk_list_item_t* pc_item;
- const tnet_stun_attr_t* pc_attr;
- if (!pc_self || !ppc_attr) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *ppc_attr = tsk_null;
- tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
- if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
- if (pc_attr->hdr.e_type == e_type && !u_index--) {
- *ppc_attr = pc_attr;
- break;
- }
- }
- }
- return 0;
+ const tsk_list_item_t* pc_item;
+ const tnet_stun_attr_t* pc_attr;
+ if (!pc_self || !ppc_attr) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *ppc_attr = tsk_null;
+ tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
+ if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
+ if (pc_attr->hdr.e_type == e_type && !u_index--) {
+ *ppc_attr = pc_attr;
+ break;
+ }
+ }
+ }
+ return 0;
}
tsk_bool_t tnet_stun_pkt_attr_exists(const tnet_stun_pkt_t* pc_self, tnet_stun_attr_type_t e_type)
{
- const tnet_stun_attr_t* pc_attr;
- int ret = tnet_stun_pkt_attr_find(pc_self, e_type, 0, &pc_attr);
- return (pc_attr && (ret == 0));
+ const tnet_stun_attr_t* pc_attr;
+ int ret = tnet_stun_pkt_attr_find(pc_self, e_type, 0, &pc_attr);
+ return (pc_attr && (ret == 0));
}
int tnet_stun_pkt_get_size_in_octetunits_without_padding(const tnet_stun_pkt_t* pc_self, tsk_size_t* p_size)
{
- const tsk_list_item_t* pc_item;
- const tnet_stun_attr_t* pc_attr;
- tsk_size_t n_size;
- int ret;
- if (!pc_self || !p_size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *p_size = kStunPktHdrSizeInOctets;
- tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
- if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
- if ((ret = tnet_stun_attr_get_size_in_octetunits_without_padding(pc_attr, &n_size))) {
- return ret;
- }
- *p_size += n_size;
- }
- }
- if (pc_self->opt.fingerprint) {
- *p_size += kStunAttrHdrSizeInOctets + 4;
- }
- if (pc_self->opt.dontfrag) {
- *p_size += kStunAttrHdrSizeInOctets;
- }
- return 0;
+ const tsk_list_item_t* pc_item;
+ const tnet_stun_attr_t* pc_attr;
+ tsk_size_t n_size;
+ int ret;
+ if (!pc_self || !p_size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *p_size = kStunPktHdrSizeInOctets;
+ tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
+ if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
+ if ((ret = tnet_stun_attr_get_size_in_octetunits_without_padding(pc_attr, &n_size))) {
+ return ret;
+ }
+ *p_size += n_size;
+ }
+ }
+ if (pc_self->opt.fingerprint) {
+ *p_size += kStunAttrHdrSizeInOctets + 4;
+ }
+ if (pc_self->opt.dontfrag) {
+ *p_size += kStunAttrHdrSizeInOctets;
+ }
+ return 0;
}
int tnet_stun_pkt_get_size_in_octetunits_with_padding(const tnet_stun_pkt_t* pc_self, tsk_size_t* p_size)
{
- const tsk_list_item_t* pc_item;
- const tnet_stun_attr_t* pc_attr;
- tsk_size_t n_size;
- int ret;
- if (!pc_self || !p_size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *p_size = kStunPktHdrSizeInOctets;
- tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
- if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
- if ((ret = tnet_stun_attr_get_size_in_octetunits_with_padding(pc_attr, &n_size))) {
- return ret;
- }
- *p_size += n_size;
- }
- }
- if (pc_self->opt.fingerprint) {
- *p_size += kStunAttrHdrSizeInOctets + 4;
- }
- if (pc_self->opt.dontfrag) {
- *p_size += kStunAttrHdrSizeInOctets;
- }
- return 0;
+ const tsk_list_item_t* pc_item;
+ const tnet_stun_attr_t* pc_attr;
+ tsk_size_t n_size;
+ int ret;
+ if (!pc_self || !p_size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *p_size = kStunPktHdrSizeInOctets;
+ tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
+ if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
+ if ((ret = tnet_stun_attr_get_size_in_octetunits_with_padding(pc_attr, &n_size))) {
+ return ret;
+ }
+ *p_size += n_size;
+ }
+ }
+ if (pc_self->opt.fingerprint) {
+ *p_size += kStunAttrHdrSizeInOctets + 4;
+ }
+ if (pc_self->opt.dontfrag) {
+ *p_size += kStunAttrHdrSizeInOctets;
+ }
+ return 0;
}
int tnet_stun_pkt_write_with_padding(const tnet_stun_pkt_t* pc_self, uint8_t* p_buff_ptr, tsk_size_t n_buff_size, tsk_size_t *p_written)
{
- const tsk_list_item_t* pc_item;
- const tnet_stun_attr_t* pc_attr;
- tsk_size_t n_size;
- int ret;
- uint8_t *_p_buff_ptr = p_buff_ptr, *_p_msg_int_start;
- if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, p_written))) {
- return ret;
- }
- if ((n_buff_size < *p_written)) {
- TSK_DEBUG_ERROR("Buffer too short: %u<%u", (unsigned)n_buff_size, (unsigned)*p_written);
- return -1;
- }
-
- // write header
- *((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->e_type);
- *((uint32_t*)&p_buff_ptr[4]) = (uint32_t)tnet_htonl(kStunMagicCookie);
- memcpy(&p_buff_ptr[8], pc_self->transac_id, sizeof(pc_self->transac_id));
-
- p_buff_ptr += kStunPktHdrSizeInOctets;
- n_buff_size -= kStunPktHdrSizeInOctets;
-
- // write attributes
- tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
- if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
- if ((pc_attr->hdr.e_type == tnet_stun_attr_type_message_integrity)) {
- continue; // because 'MESSAGE-INTEGRITY' must be the latest attribute
- }
- if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
- return ret;
- }
- p_buff_ptr += n_size;
- n_buff_size -= n_size;
- }
- }
-
- // DONT-FRAGMENT
- if (pc_self->opt.dontfrag && tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_dont_fragment, &pc_attr) == 0 && !pc_attr) {
- *((uint16_t*)&p_buff_ptr[0]) = tnet_htons(tnet_stun_attr_type_dont_fragment); // Type
- *((uint16_t*)&p_buff_ptr[2]) = 0; // Length
- p_buff_ptr += 4;
- }
-
- // MESSAGE-INTEGRITY
- if (!tsk_strnullORempty(pc_self->p_pwd) && tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_message_integrity, &pc_attr) == 0 && pc_attr) {
- /* RFC 5389 - 15.4. MESSAGE-INTEGRITY
- The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
-
- For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
- For short-term credentials ==> key = SASLprep(password)
- */
-
- tsk_sha1digest_t hmac;
- const tnet_stun_attr_vdata_t *pc_attr_username = tsk_null, *pc_attr_realm = tsk_null, *pc_attr_nonce = tsk_null;
- static const uint16_t kMsgIntTotalLength = kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE;
- _p_msg_int_start = p_buff_ptr;
-
- // write attribute
- if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
- return ret;
- }
- p_buff_ptr += n_size;
- n_buff_size -= n_size;
-
- // Length (must be correct before computing message integrity)
- *((uint16_t*)&_p_buff_ptr[2]) = tnet_htons((unsigned short)((p_buff_ptr - _p_buff_ptr) - kStunPktHdrSizeInOctets));
-
- if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_username, (const tnet_stun_attr_t**)&pc_attr_username))) {
- return ret;
- }
- if (pc_attr_username) {
- if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr_realm))) {
- return ret;
- }
- if (pc_attr_realm) {
- if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce))) {
- return ret;
- }
- }
- }
- if (pc_attr_username && pc_attr_realm && pc_attr_nonce) {
- // LONG-TERM
- char* p_keystr = tsk_null;
- tsk_md5digest_t md5;
- tsk_sprintf(&p_keystr, "%s:%s:%s", pc_attr_username->p_data_ptr, pc_attr_realm->p_data_ptr, pc_self->p_pwd);
- TSK_MD5_DIGEST_CALC(p_keystr, (tsk_size_t)tsk_strlen(p_keystr), md5);
- hmac_sha1digest_compute(_p_buff_ptr, (tsk_size_t)(_p_msg_int_start - _p_buff_ptr), (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
- TSK_FREE(p_keystr);
- }
- else {
- // SHORT-TERM
- hmac_sha1digest_compute(_p_buff_ptr, (tsk_size_t)(_p_msg_int_start - _p_buff_ptr), pc_self->p_pwd, (tsk_size_t)tsk_strlen(pc_self->p_pwd), hmac);
- }
-
- // update MESSAGE-INTEGRITY attribute value
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, hmac, TSK_SHA1_DIGEST_SIZE))) {
- return ret;
- }
- if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, _p_msg_int_start, kMsgIntTotalLength, &n_size))) {
- return ret;
- }
- }
-
- // Length before computing FINGERPRINT
- *((uint16_t*)&_p_buff_ptr[2]) = tnet_htons((unsigned short)((p_buff_ptr - _p_buff_ptr) - kStunPktHdrSizeInOctets + ((pc_self->opt.fingerprint && (p_buff_ptr - _p_buff_ptr) >= 8) ? 8 : 0)));
-
- if (pc_self->opt.fingerprint && (p_buff_ptr - _p_buff_ptr) >= 8) {
- /* RFC 5389 - 15.5. FINGERPRINT
- The FINGERPRINT attribute MAY be present in all STUN messages. The
- value of the attribute is computed as the CRC-32 of the STUN message
- up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
- the 32-bit value 0x5354554e
- */
- uint32_t u_fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, _p_buff_ptr, (int32_t)(p_buff_ptr - _p_buff_ptr)) ^ kStunFingerprintXorConst;
- *((uint16_t*)&p_buff_ptr[0]) = tnet_htons(tnet_stun_attr_type_fingerprint); // Type
- *((uint16_t*)&p_buff_ptr[2]) = tnet_htons(4); // Length
- *((uint32_t*)&p_buff_ptr[4]) = (uint32_t)tnet_htonl(u_fingerprint);
- p_buff_ptr += 8;
- }
-
- *p_written = (tsk_size_t)(p_buff_ptr - _p_buff_ptr);
- return 0;
+ const tsk_list_item_t* pc_item;
+ const tnet_stun_attr_t* pc_attr;
+ tsk_size_t n_size;
+ int ret;
+ uint8_t *_p_buff_ptr = p_buff_ptr, *_p_msg_int_start;
+ if (!pc_self || !p_buff_ptr || !n_buff_size || !p_written) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, p_written))) {
+ return ret;
+ }
+ if ((n_buff_size < *p_written)) {
+ TSK_DEBUG_ERROR("Buffer too short: %u<%u", (unsigned)n_buff_size, (unsigned)*p_written);
+ return -1;
+ }
+
+ // write header
+ *((uint16_t*)&p_buff_ptr[0]) = tnet_htons((unsigned short)pc_self->e_type);
+ *((uint32_t*)&p_buff_ptr[4]) = (uint32_t)tnet_htonl(kStunMagicCookie);
+ memcpy(&p_buff_ptr[8], pc_self->transac_id, sizeof(pc_self->transac_id));
+
+ p_buff_ptr += kStunPktHdrSizeInOctets;
+ n_buff_size -= kStunPktHdrSizeInOctets;
+
+ // write attributes
+ tsk_list_foreach(pc_item, pc_self->p_list_attrs) {
+ if ((pc_attr = (const tnet_stun_attr_t*)pc_item->data)) {
+ if ((pc_attr->hdr.e_type == tnet_stun_attr_type_message_integrity)) {
+ continue; // because 'MESSAGE-INTEGRITY' must be the latest attribute
+ }
+ if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
+ return ret;
+ }
+ p_buff_ptr += n_size;
+ n_buff_size -= n_size;
+ }
+ }
+
+ // DONT-FRAGMENT
+ if (pc_self->opt.dontfrag && tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_dont_fragment, &pc_attr) == 0 && !pc_attr) {
+ *((uint16_t*)&p_buff_ptr[0]) = tnet_htons(tnet_stun_attr_type_dont_fragment); // Type
+ *((uint16_t*)&p_buff_ptr[2]) = 0; // Length
+ p_buff_ptr += 4;
+ }
+
+ // MESSAGE-INTEGRITY
+ if (!tsk_strnullORempty(pc_self->p_pwd) && tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_message_integrity, &pc_attr) == 0 && pc_attr) {
+ /* RFC 5389 - 15.4. MESSAGE-INTEGRITY
+ The MESSAGE-INTEGRITY attribute contains an HMAC-SHA1 [RFC2104] of the STUN message.
+
+ For long-term credentials ==> key = MD5(username ":" realm ":" SASLprep(password))
+ For short-term credentials ==> key = SASLprep(password)
+ */
+
+ tsk_sha1digest_t hmac;
+ const tnet_stun_attr_vdata_t *pc_attr_username = tsk_null, *pc_attr_realm = tsk_null, *pc_attr_nonce = tsk_null;
+ static const uint16_t kMsgIntTotalLength = kStunAttrHdrSizeInOctets + TSK_SHA1_DIGEST_SIZE;
+ _p_msg_int_start = p_buff_ptr;
+
+ // write attribute
+ if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, p_buff_ptr, n_buff_size, &n_size))) {
+ return ret;
+ }
+ p_buff_ptr += n_size;
+ n_buff_size -= n_size;
+
+ // Length (must be correct before computing message integrity)
+ *((uint16_t*)&_p_buff_ptr[2]) = tnet_htons((unsigned short)((p_buff_ptr - _p_buff_ptr) - kStunPktHdrSizeInOctets));
+
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_username, (const tnet_stun_attr_t**)&pc_attr_username))) {
+ return ret;
+ }
+ if (pc_attr_username) {
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr_realm))) {
+ return ret;
+ }
+ if (pc_attr_realm) {
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce))) {
+ return ret;
+ }
+ }
+ }
+ if (pc_attr_username && pc_attr_realm && pc_attr_nonce) {
+ // LONG-TERM
+ char* p_keystr = tsk_null;
+ tsk_md5digest_t md5;
+ tsk_sprintf(&p_keystr, "%s:%s:%s", pc_attr_username->p_data_ptr, pc_attr_realm->p_data_ptr, pc_self->p_pwd);
+ TSK_MD5_DIGEST_CALC(p_keystr, (tsk_size_t)tsk_strlen(p_keystr), md5);
+ hmac_sha1digest_compute(_p_buff_ptr, (tsk_size_t)(_p_msg_int_start - _p_buff_ptr), (const char*)md5, TSK_MD5_DIGEST_SIZE, hmac);
+ TSK_FREE(p_keystr);
+ }
+ else {
+ // SHORT-TERM
+ hmac_sha1digest_compute(_p_buff_ptr, (tsk_size_t)(_p_msg_int_start - _p_buff_ptr), pc_self->p_pwd, (tsk_size_t)tsk_strlen(pc_self->p_pwd), hmac);
+ }
+
+ // update MESSAGE-INTEGRITY attribute value
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, hmac, TSK_SHA1_DIGEST_SIZE))) {
+ return ret;
+ }
+ if ((ret = tnet_stun_attr_write_with_padding(&pc_self->transac_id, pc_attr, _p_msg_int_start, kMsgIntTotalLength, &n_size))) {
+ return ret;
+ }
+ }
+
+ // Length before computing FINGERPRINT
+ *((uint16_t*)&_p_buff_ptr[2]) = tnet_htons((unsigned short)((p_buff_ptr - _p_buff_ptr) - kStunPktHdrSizeInOctets + ((pc_self->opt.fingerprint && (p_buff_ptr - _p_buff_ptr) >= 8) ? 8 : 0)));
+
+ if (pc_self->opt.fingerprint && (p_buff_ptr - _p_buff_ptr) >= 8) {
+ /* RFC 5389 - 15.5. FINGERPRINT
+ The FINGERPRINT attribute MAY be present in all STUN messages. The
+ value of the attribute is computed as the CRC-32 of the STUN message
+ up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
+ the 32-bit value 0x5354554e
+ */
+ uint32_t u_fingerprint = tsk_pppfcs32(TSK_PPPINITFCS32, _p_buff_ptr, (int32_t)(p_buff_ptr - _p_buff_ptr)) ^ kStunFingerprintXorConst;
+ *((uint16_t*)&p_buff_ptr[0]) = tnet_htons(tnet_stun_attr_type_fingerprint); // Type
+ *((uint16_t*)&p_buff_ptr[2]) = tnet_htons(4); // Length
+ *((uint32_t*)&p_buff_ptr[4]) = (uint32_t)tnet_htonl(u_fingerprint);
+ p_buff_ptr += 8;
+ }
+
+ *p_written = (tsk_size_t)(p_buff_ptr - _p_buff_ptr);
+ return 0;
}
int tnet_stun_pkt_write_with_padding_2(const struct tnet_stun_pkt_s* pc_self, struct tsk_buffer_s** pp_buff)
{
- tsk_size_t u_buff_size;
- int ret;
- if (!pc_self || !pp_buff) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *pp_buff = tsk_null;
- if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, &u_buff_size))) {
- goto bail;
- }
- u_buff_size += kStunBuffMinPad;
- if (!(*pp_buff = tsk_buffer_create(tsk_null, u_buff_size))) {
- goto bail;
- }
- if ((ret = tnet_stun_pkt_write_with_padding(pc_self, (*pp_buff)->data, (*pp_buff)->size, &(*pp_buff)->size))) {
- goto bail;
- }
+ tsk_size_t u_buff_size;
+ int ret;
+ if (!pc_self || !pp_buff) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *pp_buff = tsk_null;
+ if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_self, &u_buff_size))) {
+ goto bail;
+ }
+ u_buff_size += kStunBuffMinPad;
+ if (!(*pp_buff = tsk_buffer_create(tsk_null, u_buff_size))) {
+ goto bail;
+ }
+ if ((ret = tnet_stun_pkt_write_with_padding(pc_self, (*pp_buff)->data, (*pp_buff)->size, &(*pp_buff)->size))) {
+ goto bail;
+ }
bail:
- if (ret) {
- TSK_OBJECT_SAFE_FREE(*pp_buff);
- }
- return ret;
+ if (ret) {
+ TSK_OBJECT_SAFE_FREE(*pp_buff);
+ }
+ return ret;
}
int tnet_stun_pkt_is_complete(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tsk_bool_t *pb_is_complete)
{
- if (!pb_is_complete) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *pb_is_complete = tsk_false;
- if (pc_buff_ptr && n_buff_size >= kStunPktHdrSizeInOctets) {
- tsk_size_t n_paylen_in_octets = tnet_ntohs_2(&pc_buff_ptr[2]);
- *pb_is_complete = ((n_buff_size - kStunPktHdrSizeInOctets) >= n_paylen_in_octets);
- }
- return 0;
+ if (!pb_is_complete) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *pb_is_complete = tsk_false;
+ if (pc_buff_ptr && n_buff_size >= kStunPktHdrSizeInOctets) {
+ tsk_size_t n_paylen_in_octets = tnet_ntohs_2(&pc_buff_ptr[2]);
+ *pb_is_complete = ((n_buff_size - kStunPktHdrSizeInOctets) >= n_paylen_in_octets);
+ }
+ return 0;
}
int tnet_stun_pkt_read(const uint8_t* pc_buff_ptr, tsk_size_t n_buff_size, tnet_stun_pkt_t** pp_pkt)
{
- tsk_bool_t b_is_complete;
- uint16_t PayloadLengthInOctets;
- tnet_stun_pkt_type_t Type;
- tnet_stun_transac_id_t transac_id;
- uint32_t MagicCookie;
- int ret;
-
- if (!pc_buff_ptr || !n_buff_size || !pp_pkt) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (!TNET_STUN_BUFF_IS_STUN2(pc_buff_ptr, n_buff_size)) {
- TSK_DEBUG_ERROR("Buffer doesn't contain a valid STUN2 pkt");
- return -2;
- }
- if ((ret = tnet_stun_pkt_is_complete(pc_buff_ptr, n_buff_size, &b_is_complete))) {
- return ret;
- }
- if (!b_is_complete) {
- TSK_DEBUG_ERROR("Buffer too short(%u)", (unsigned)n_buff_size);
- return -3;
- }
-
- // read the header
- Type = tnet_ntohs_2(&pc_buff_ptr[0]);
- PayloadLengthInOctets = tnet_ntohs_2(&pc_buff_ptr[2]);
- MagicCookie = (uint32_t)tnet_ntohl_2(&pc_buff_ptr[4]);
- if (MagicCookie != kStunMagicCookieLong) {
- TSK_DEBUG_ERROR("%x not a valid STUN2 magic cookie", MagicCookie);
- return -4;
- }
- memcpy(transac_id, &pc_buff_ptr[8], sizeof(tnet_stun_transac_id_t));
- // create the pkt
- if ((ret = tnet_stun_pkt_create(Type, PayloadLengthInOctets, (const tnet_stun_transac_id_t*)&transac_id, pp_pkt))) {
- return ret;
- }
-
- if (PayloadLengthInOctets > 0) {
- tnet_stun_attr_t* p_attr;
- tsk_size_t n_consumed_octets;
- pc_buff_ptr += kStunPktHdrSizeInOctets;
- do {
- if ((ret = tnet_stun_attr_read((const tnet_stun_transac_id_t*)&(*pp_pkt)->transac_id, pc_buff_ptr, PayloadLengthInOctets, &n_consumed_octets, &p_attr))) {
- return ret;
- }
- if ((ret = tnet_stun_pkt_attr_add((*pp_pkt), &p_attr))) {
- TSK_OBJECT_SAFE_FREE((*pp_pkt));
- return ret;
- }
- PayloadLengthInOctets -= (uint16_t)n_consumed_octets;
- pc_buff_ptr += n_consumed_octets;
- } while (PayloadLengthInOctets >= kStunAttrHdrSizeInOctets);
- }
-
- return 0;
+ tsk_bool_t b_is_complete;
+ uint16_t PayloadLengthInOctets;
+ tnet_stun_pkt_type_t Type;
+ tnet_stun_transac_id_t transac_id;
+ uint32_t MagicCookie;
+ int ret;
+
+ if (!pc_buff_ptr || !n_buff_size || !pp_pkt) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (!TNET_STUN_BUFF_IS_STUN2(pc_buff_ptr, n_buff_size)) {
+ TSK_DEBUG_ERROR("Buffer doesn't contain a valid STUN2 pkt");
+ return -2;
+ }
+ if ((ret = tnet_stun_pkt_is_complete(pc_buff_ptr, n_buff_size, &b_is_complete))) {
+ return ret;
+ }
+ if (!b_is_complete) {
+ TSK_DEBUG_ERROR("Buffer too short(%u)", (unsigned)n_buff_size);
+ return -3;
+ }
+
+ // read the header
+ Type = tnet_ntohs_2(&pc_buff_ptr[0]);
+ PayloadLengthInOctets = tnet_ntohs_2(&pc_buff_ptr[2]);
+ MagicCookie = (uint32_t)tnet_ntohl_2(&pc_buff_ptr[4]);
+ if (MagicCookie != kStunMagicCookieLong) {
+ TSK_DEBUG_ERROR("%x not a valid STUN2 magic cookie", MagicCookie);
+ return -4;
+ }
+ memcpy(transac_id, &pc_buff_ptr[8], sizeof(tnet_stun_transac_id_t));
+ // create the pkt
+ if ((ret = tnet_stun_pkt_create(Type, PayloadLengthInOctets, (const tnet_stun_transac_id_t*)&transac_id, pp_pkt))) {
+ return ret;
+ }
+
+ if (PayloadLengthInOctets > 0) {
+ tnet_stun_attr_t* p_attr;
+ tsk_size_t n_consumed_octets;
+ pc_buff_ptr += kStunPktHdrSizeInOctets;
+ do {
+ if ((ret = tnet_stun_attr_read((const tnet_stun_transac_id_t*)&(*pp_pkt)->transac_id, pc_buff_ptr, PayloadLengthInOctets, &n_consumed_octets, &p_attr))) {
+ return ret;
+ }
+ if ((ret = tnet_stun_pkt_attr_add((*pp_pkt), &p_attr))) {
+ TSK_OBJECT_SAFE_FREE((*pp_pkt));
+ return ret;
+ }
+ PayloadLengthInOctets -= (uint16_t)n_consumed_octets;
+ pc_buff_ptr += n_consumed_octets;
+ }
+ while (PayloadLengthInOctets >= kStunAttrHdrSizeInOctets);
+ }
+
+ return 0;
}
int tnet_stun_pkt_auth_prepare(tnet_stun_pkt_t* p_self, const char* pc_usr_name, const char* pc_pwd, const char* pc_realm, const char* pc_nonce)
{
- const tnet_stun_attr_t* pc_attr;
- int ret;
- static const tsk_sha1digest_t __pc_sha1digestEmpty = { 0 };
- static const uint16_t __u_sha1digestEmpty = sizeof(__pc_sha1digestEmpty);
- if (!p_self /*|| !pc_usr_name*/ || !pc_pwd /*|| !pc_realm || !pc_nonce*/) { // "username", "realm" and "nonce" are null for short-term authentication
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- // USERNAME
- if (pc_usr_name) { // LONG-TERM, optional for SHORT-TERM
- if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_username, &pc_attr))) {
- goto bail;
- }
- if (pc_attr) {
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_usr_name, (uint16_t)tsk_strlen(pc_usr_name)))) {
- goto bail;
- }
- }
- else {
- ret = tnet_stun_pkt_attrs_add(p_self,
- TNET_STUN_PKT_ATTR_ADD_USERNAME_ZT(pc_usr_name),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- // REALM
- if (pc_realm) { // LONG-TERM
- if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_realm, &pc_attr))) {
- goto bail;
- }
- if (pc_attr) {
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_realm, (uint16_t)tsk_strlen(pc_realm)))) {
- goto bail;
- }
- }
- else {
- ret = tnet_stun_pkt_attrs_add(p_self,
- TNET_STUN_PKT_ATTR_ADD_REALM_ZT(pc_realm),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- // NONCE
- if (pc_nonce) { // LONG-TERM
- if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_nonce, &pc_attr))) {
- goto bail;
- }
- if (pc_attr) {
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_nonce, (uint16_t)tsk_strlen(pc_nonce)))) {
- goto bail;
- }
- }
- else {
- ret = tnet_stun_pkt_attrs_add(p_self,
- TNET_STUN_PKT_ATTR_ADD_NONCE_ZT(pc_nonce),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- }
- // MESSAGE-INTEGRITY
- if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_message_integrity, &pc_attr))) {
- goto bail;
- }
- if (!pc_attr) {
- ret = tnet_stun_pkt_attrs_add(p_self,
- TNET_STUN_PKT_ATTR_ADD_MESSAGE_INTEGRITY(__pc_sha1digestEmpty, __u_sha1digestEmpty),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
-
- // PASSWORD
- tsk_strupdate(&p_self->p_pwd, pc_pwd);
+ const tnet_stun_attr_t* pc_attr;
+ int ret;
+ static const tsk_sha1digest_t __pc_sha1digestEmpty = { 0 };
+ static const uint16_t __u_sha1digestEmpty = sizeof(__pc_sha1digestEmpty);
+ if (!p_self /*|| !pc_usr_name*/ || !pc_pwd /*|| !pc_realm || !pc_nonce*/) { // "username", "realm" and "nonce" are null for short-term authentication
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ // USERNAME
+ if (pc_usr_name) { // LONG-TERM, optional for SHORT-TERM
+ if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_username, &pc_attr))) {
+ goto bail;
+ }
+ if (pc_attr) {
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_usr_name, (uint16_t)tsk_strlen(pc_usr_name)))) {
+ goto bail;
+ }
+ }
+ else {
+ ret = tnet_stun_pkt_attrs_add(p_self,
+ TNET_STUN_PKT_ATTR_ADD_USERNAME_ZT(pc_usr_name),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ }
+ // REALM
+ if (pc_realm) { // LONG-TERM
+ if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_realm, &pc_attr))) {
+ goto bail;
+ }
+ if (pc_attr) {
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_realm, (uint16_t)tsk_strlen(pc_realm)))) {
+ goto bail;
+ }
+ }
+ else {
+ ret = tnet_stun_pkt_attrs_add(p_self,
+ TNET_STUN_PKT_ATTR_ADD_REALM_ZT(pc_realm),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ }
+ // NONCE
+ if (pc_nonce) { // LONG-TERM
+ if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_nonce, &pc_attr))) {
+ goto bail;
+ }
+ if (pc_attr) {
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr, (const uint8_t*)pc_nonce, (uint16_t)tsk_strlen(pc_nonce)))) {
+ goto bail;
+ }
+ }
+ else {
+ ret = tnet_stun_pkt_attrs_add(p_self,
+ TNET_STUN_PKT_ATTR_ADD_NONCE_ZT(pc_nonce),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ }
+ // MESSAGE-INTEGRITY
+ if ((ret = tnet_stun_pkt_attr_find_first(p_self, tnet_stun_attr_type_message_integrity, &pc_attr))) {
+ goto bail;
+ }
+ if (!pc_attr) {
+ ret = tnet_stun_pkt_attrs_add(p_self,
+ TNET_STUN_PKT_ATTR_ADD_MESSAGE_INTEGRITY(__pc_sha1digestEmpty, __u_sha1digestEmpty),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+
+ // PASSWORD
+ tsk_strupdate(&p_self->p_pwd, pc_pwd);
bail:
- return ret;
+ return ret;
}
// pc_resp = 401 or 438
int tnet_stun_pkt_auth_prepare_2(struct tnet_stun_pkt_s* p_self, const char* pc_usr_name, const char* pc_pwd, const struct tnet_stun_pkt_s* pc_resp)
{
- const tnet_stun_attr_vdata_t* pc_attr;
- const char *pc_nonce, *pc_realm;
- int ret;
- if (!p_self || !pc_usr_name || !pc_pwd || !pc_resp) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- // NONCE
- if ((ret = tnet_stun_pkt_attr_find_first(pc_resp, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr))) {
- goto bail;
- }
- if (!pc_attr || !pc_attr->p_data_ptr || !pc_attr->u_data_size) {
- TSK_DEBUG_ERROR("Invalid NONCE in 401");
- ret = -3;
- goto bail;
- }
- pc_nonce = (const char*)pc_attr->p_data_ptr;
- // REALM
- if ((ret = tnet_stun_pkt_attr_find_first(pc_resp, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr))) {
- goto bail;
- }
- if (!pc_attr || !pc_attr->p_data_ptr || !pc_attr->u_data_size) {
- TSK_DEBUG_ERROR("Invalid REALM in 401");
- ret = -3;
- goto bail;
- }
- pc_realm = (const char*)pc_attr->p_data_ptr;
-
- if ((ret = tnet_stun_pkt_auth_prepare(p_self, pc_usr_name, pc_pwd, pc_realm, pc_nonce))) {
- goto bail;
- }
-
- // TRANSACTION-ID
- if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
- goto bail;
- }
+ const tnet_stun_attr_vdata_t* pc_attr;
+ const char *pc_nonce, *pc_realm;
+ int ret;
+ if (!p_self || !pc_usr_name || !pc_pwd || !pc_resp) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ // NONCE
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_resp, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr))) {
+ goto bail;
+ }
+ if (!pc_attr || !pc_attr->p_data_ptr || !pc_attr->u_data_size) {
+ TSK_DEBUG_ERROR("Invalid NONCE in 401");
+ ret = -3;
+ goto bail;
+ }
+ pc_nonce = (const char*)pc_attr->p_data_ptr;
+ // REALM
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_resp, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr))) {
+ goto bail;
+ }
+ if (!pc_attr || !pc_attr->p_data_ptr || !pc_attr->u_data_size) {
+ TSK_DEBUG_ERROR("Invalid REALM in 401");
+ ret = -3;
+ goto bail;
+ }
+ pc_realm = (const char*)pc_attr->p_data_ptr;
+
+ if ((ret = tnet_stun_pkt_auth_prepare(p_self, pc_usr_name, pc_pwd, pc_realm, pc_nonce))) {
+ goto bail;
+ }
+
+ // TRANSACTION-ID
+ if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
+ goto bail;
+ }
bail:
- return ret;
+ return ret;
}
int tnet_stun_pkt_auth_copy(tnet_stun_pkt_t* p_self, const char* pc_usr_name, const char* pc_pwd, const tnet_stun_pkt_t* pc_pkt)
{
- const tnet_stun_attr_vdata_t *pc_attr_realm = tsk_null, *pc_attr_nonce = tsk_null;
- int ret;
- tsk_bool_t b_ok;
- if (!p_self || !pc_pwd || !pc_usr_name || !pc_pkt) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- b_ok =
- (ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr_realm)) == 0 && pc_attr_realm
- && (ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce)) == 0 && pc_attr_nonce;
-
- if (b_ok && (ret = tnet_stun_pkt_auth_prepare(p_self, pc_usr_name, pc_pwd, (const char*)pc_attr_realm->p_data_ptr, (const char*)pc_attr_nonce->p_data_ptr))) {
- goto bail;
- }
+ const tnet_stun_attr_vdata_t *pc_attr_realm = tsk_null, *pc_attr_nonce = tsk_null;
+ int ret;
+ tsk_bool_t b_ok;
+ if (!p_self || !pc_pwd || !pc_usr_name || !pc_pkt) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ b_ok =
+ (ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_realm, (const tnet_stun_attr_t**)&pc_attr_realm)) == 0 && pc_attr_realm
+ && (ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce)) == 0 && pc_attr_nonce;
+
+ if (b_ok && (ret = tnet_stun_pkt_auth_prepare(p_self, pc_usr_name, pc_pwd, (const char*)pc_attr_realm->p_data_ptr, (const char*)pc_attr_nonce->p_data_ptr))) {
+ goto bail;
+ }
bail:
- return ret;
+ return ret;
}
int tnet_stun_pkt_get_errorcode(const struct tnet_stun_pkt_s* pc_self, uint16_t* pu_code)
{
- const tnet_stun_attr_error_code_t* pc_attr;
- int ret;
- if (!pc_self && !pu_code) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *pu_code = 0;
- if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_error_code, (const tnet_stun_attr_t**)&pc_attr))) {
- return ret;
- }
- if (pc_attr) {
- *pu_code = (pc_attr->u_class * 100) + pc_attr->u_number;
- }
- return 0;
+ const tnet_stun_attr_error_code_t* pc_attr;
+ int ret;
+ if (!pc_self && !pu_code) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *pu_code = 0;
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_self, tnet_stun_attr_type_error_code, (const tnet_stun_attr_t**)&pc_attr))) {
+ return ret;
+ }
+ if (pc_attr) {
+ *pu_code = (pc_attr->u_class * 100) + pc_attr->u_number;
+ }
+ return 0;
}
int tnet_stun_pkt_process_err420(struct tnet_stun_pkt_s *p_self, const struct tnet_stun_pkt_s *pc_pkt_resp420)
{
- const tnet_stun_attr_vdata_t* pc_attr;
- uint16_t u16;
- int ret;
- tsk_bool_t b_done = tsk_false;
- if (!p_self || !pc_pkt_resp420) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt_resp420, tnet_stun_attr_type_unknown_attrs, (const tnet_stun_attr_t**)&pc_attr))) {
- goto bail;
- }
- if (!pc_attr || !pc_attr->p_data_ptr || (pc_attr->u_data_size & 1)) {
- TSK_DEBUG_ERROR("UNKNOWN-ATTRIBUTES missing in 420");
- ret = -3;
- goto bail;
- }
- for (u16 = 0; u16 < pc_attr->u_data_size; u16 += 2) {
- switch (*((uint16_t*)&pc_attr->p_data_ptr[u16])) {
- case tnet_stun_attr_type_dont_fragment: {
- p_self->opt.dontfrag = 0;
- b_done = tsk_true;
- break;
- }
- case tnet_stun_attr_type_fingerprint: {
- p_self->opt.fingerprint = 0;
- b_done = tsk_true;
- break;
- }
- }
- }
-
- if (b_done) {
- // TRANSACTION-ID
- if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
- goto bail;
- }
- }
+ const tnet_stun_attr_vdata_t* pc_attr;
+ uint16_t u16;
+ int ret;
+ tsk_bool_t b_done = tsk_false;
+ if (!p_self || !pc_pkt_resp420) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt_resp420, tnet_stun_attr_type_unknown_attrs, (const tnet_stun_attr_t**)&pc_attr))) {
+ goto bail;
+ }
+ if (!pc_attr || !pc_attr->p_data_ptr || (pc_attr->u_data_size & 1)) {
+ TSK_DEBUG_ERROR("UNKNOWN-ATTRIBUTES missing in 420");
+ ret = -3;
+ goto bail;
+ }
+ for (u16 = 0; u16 < pc_attr->u_data_size; u16 += 2) {
+ switch (*((uint16_t*)&pc_attr->p_data_ptr[u16])) {
+ case tnet_stun_attr_type_dont_fragment: {
+ p_self->opt.dontfrag = 0;
+ b_done = tsk_true;
+ break;
+ }
+ case tnet_stun_attr_type_fingerprint: {
+ p_self->opt.fingerprint = 0;
+ b_done = tsk_true;
+ break;
+ }
+ }
+ }
+
+ if (b_done) {
+ // TRANSACTION-ID
+ if ((ret = tnet_stun_utils_transac_id_rand(&p_self->transac_id))) {
+ goto bail;
+ }
+ }
bail:
- return ret;
+ return ret;
}
static tsk_object_t* tnet_stun_pkt_ctor(tsk_object_t * self, va_list * app)
{
- tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
- if (p_pkt) {
- p_pkt->opt.fingerprint = kStunOptFingerPrint;
- p_pkt->opt.dontfrag = kStunOptDontFragment;
- }
- return self;
+ tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
+ if (p_pkt) {
+ p_pkt->opt.fingerprint = kStunOptFingerPrint;
+ p_pkt->opt.dontfrag = kStunOptDontFragment;
+ }
+ return self;
}
static tsk_object_t* tnet_stun_pkt_dtor(tsk_object_t * self)
{
- tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
- if (p_pkt) {
+ tnet_stun_pkt_t *p_pkt = (tnet_stun_pkt_t *)self;
+ if (p_pkt) {
#if PRINT_DESTROYED_MSG
- TSK_DEBUG_INFO("*** STUN pkt destroyed ***");
+ TSK_DEBUG_INFO("*** STUN pkt destroyed ***");
#endif
- TSK_OBJECT_SAFE_FREE(p_pkt->p_list_attrs);
- TSK_FREE(p_pkt->p_pwd);
- }
- return self;
+ TSK_OBJECT_SAFE_FREE(p_pkt->p_list_attrs);
+ TSK_FREE(p_pkt->p_pwd);
+ }
+ return self;
}
static const tsk_object_def_t tnet_stun_pkt_def_s = {
- sizeof(tnet_stun_pkt_t),
- tnet_stun_pkt_ctor,
- tnet_stun_pkt_dtor,
- tsk_null,
+ sizeof(tnet_stun_pkt_t),
+ tnet_stun_pkt_ctor,
+ tnet_stun_pkt_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_stun_pkt_def_t = &tnet_stun_pkt_def_s;
diff --git a/tinyNET/src/stun/tnet_stun_types.h b/tinyNET/src/stun/tnet_stun_types.h
index 386f471..d09bf99 100755
--- a/tinyNET/src/stun/tnet_stun_types.h
+++ b/tinyNET/src/stun/tnet_stun_types.h
@@ -141,9 +141,9 @@ typedef enum tnet_stun_method_e {
tnet_stun_method_data = 0x0007, /**< rfc5766 - Data (only indication semantics defined) */
tnet_stun_method_createpermission = 0x0008, /**< rfc5766 - CreatePermission (only request/response semantics defined */
tnet_stun_method_channelbind = 0x0009, /**< rfc5766 - ChannelBind (only request/response semantics defined) */
- tnet_stun_method_connect = 0x000a,/**< rfc6062 - Connect */
- tnet_stun_method_connectionbind = 0x000b,/**< rfc6062 - ConnectionBind */
- tnet_stun_method_connectionattempt = 0x000c,/**< rfc6062 - ConnectionAttempt */
+ tnet_stun_method_connect = 0x000a,/**< rfc6062 - Connect */
+ tnet_stun_method_connectionbind = 0x000b,/**< rfc6062 - ConnectionBind */
+ tnet_stun_method_connectionattempt = 0x000c,/**< rfc6062 - ConnectionAttempt */
}
tnet_stun_method_t;
@@ -167,8 +167,8 @@ typedef enum tnet_stun_address_family_e {
// rfc5766 - 14.7. REQUESTED-TRANSPORT
typedef enum tnet_turn_transport_e {
- tnet_turn_transport_udp = 17,
- tnet_turn_transport_tcp = 6
+ tnet_turn_transport_udp = 17,
+ tnet_turn_transport_tcp = 6
}
tnet_turn_transport_t;
@@ -257,8 +257,8 @@ typedef enum tnet_stun_attr_type_e {
tnet_stun_attr_type_ice_controlled = 0x8029, /**< 21.2. STUN Attributes */
tnet_stun_attr_type_ice_controlling = 0x802A, /**< 21.2. STUN Attributes */
- /* rfc6062 */
- tnet_stun_attr_type_connection_id = 0x002a, /**< 6.2. New STUN Attributes */
+ /* rfc6062 */
+ tnet_stun_attr_type_connection_id = 0x002a, /**< 6.2. New STUN Attributes */
} tnet_stun_attr_type_t;
@@ -316,17 +316,17 @@ typedef enum tnet_stun_pkt_type_e {
tnet_stun_pkt_type_channelbind_success_response = (tnet_stun_method_channelbind | tnet_stun_mask_success),
tnet_stun_pkt_type_channelbind_error_response = (tnet_stun_method_channelbind | tnet_stun_mask_error),
- tnet_stun_pkt_type_connect_request = (tnet_stun_method_connect | tnet_stun_mask_request),
+ tnet_stun_pkt_type_connect_request = (tnet_stun_method_connect | tnet_stun_mask_request),
tnet_stun_pkt_type_connect_indication = (tnet_stun_method_connect | tnet_stun_mask_indication),
tnet_stun_pkt_type_connect_success_response = (tnet_stun_method_connect | tnet_stun_mask_success),
tnet_stun_pkt_type_connect_error_response = (tnet_stun_method_connect | tnet_stun_mask_error),
- tnet_stun_pkt_type_connectionbind_request = (tnet_stun_method_connectionbind | tnet_stun_mask_request),
+ tnet_stun_pkt_type_connectionbind_request = (tnet_stun_method_connectionbind | tnet_stun_mask_request),
tnet_stun_pkt_type_connectionbind_indication = (tnet_stun_method_connectionbind | tnet_stun_mask_indication),
tnet_stun_pkt_type_connectionbind_success_response = (tnet_stun_method_connectionbind | tnet_stun_mask_success),
tnet_stun_pkt_type_connectionbind_error_response = (tnet_stun_method_connectionbind | tnet_stun_mask_error),
- tnet_stun_pkt_type_connectionattempt_indication = (tnet_stun_method_connectionattempt | tnet_stun_mask_indication),
+ tnet_stun_pkt_type_connectionattempt_indication = (tnet_stun_method_connectionattempt | tnet_stun_mask_indication),
}
tnet_stun_pkt_type_t;
diff --git a/tinyNET/src/tinynet.h b/tinyNET/src/tinynet.h
index 63df285..b888c8e 100755
--- a/tinyNET/src/tinynet.h
+++ b/tinyNET/src/tinynet.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2010-2015 Mamadou DIOP.
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/tinynet_config.h b/tinyNET/src/tinynet_config.h
index 813c2c0..2633d2f 100755
--- a/tinyNET/src/tinynet_config.h
+++ b/tinyNET/src/tinynet_config.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -98,7 +98,7 @@
# define TNET_BEGIN_DECLS extern "C" {
# define TNET_END_DECLS }
#else
-# define TNET_BEGIN_DECLS
+# define TNET_BEGIN_DECLS
# define TNET_END_DECLS
#endif
@@ -107,7 +107,7 @@
#elif defined(__GNUC__) && !defined(__APPLE__)
# define TNET_INLINE __inline
#else
-# define TNET_INLINE
+# define TNET_INLINE
#endif
/* have poll()? */
diff --git a/tinyNET/src/tls/tnet_dtls.c b/tinyNET/src/tls/tnet_dtls.c
index 6420c9e..b49bd46 100755
--- a/tinyNET/src/tls/tnet_dtls.c
+++ b/tinyNET/src/tls/tnet_dtls.c
@@ -33,46 +33,45 @@
#include "tsk_safeobj.h"
#include "tsk_debug.h"
-typedef struct tnet_dtls_socket_s
-{
- TSK_DECLARE_OBJECT;
-
- struct tnet_socket_s* wrapped_sock; /* not owner: do not try to close */
- tsk_bool_t verify_peer;
- tsk_bool_t use_srtp;
- tsk_bool_t handshake_completed;
- tsk_bool_t handshake_started;
- tsk_bool_t handshake_storedata; // whether to store handshaking data or to send it to the remote party
- tnet_dtls_setup_t setup;
-
- struct {
- void* ptr;
- tsk_size_t size;
- tsk_size_t count;
- } handshake_data;
-
- struct{
- const void* usrdata;
- tnet_dtls_socket_cb_f func;
- } cb;
-
- struct{
- tnet_fingerprint_t fp;
- tnet_dtls_hash_type_t hash;
- struct sockaddr_storage addr;
- } remote;
- struct{
- tnet_fingerprint_t fp;
- tnet_dtls_hash_type_t hash;
- } local;
+typedef struct tnet_dtls_socket_s {
+ TSK_DECLARE_OBJECT;
+
+ struct tnet_socket_s* wrapped_sock; /* not owner: do not try to close */
+ tsk_bool_t verify_peer;
+ tsk_bool_t use_srtp;
+ tsk_bool_t handshake_completed;
+ tsk_bool_t handshake_started;
+ tsk_bool_t handshake_storedata; // whether to store handshaking data or to send it to the remote party
+ tnet_dtls_setup_t setup;
+
+ struct {
+ void* ptr;
+ tsk_size_t size;
+ tsk_size_t count;
+ } handshake_data;
+
+ struct {
+ const void* usrdata;
+ tnet_dtls_socket_cb_f func;
+ } cb;
+
+ struct {
+ tnet_fingerprint_t fp;
+ tnet_dtls_hash_type_t hash;
+ struct sockaddr_storage addr;
+ } remote;
+ struct {
+ tnet_fingerprint_t fp;
+ tnet_dtls_hash_type_t hash;
+ } local;
#if HAVE_OPENSSL
- SSL *ssl;
- BIO* rbio;
- BIO* wbio;
+ SSL *ssl;
+ BIO* rbio;
+ BIO* wbio;
#endif
- TSK_DECLARE_SAFEOBJ;
+ TSK_DECLARE_SAFEOBJ;
}
tnet_dtls_socket_t;
@@ -83,18 +82,18 @@ tnet_dtls_socket_t;
tsk_bool_t tnet_dtls_is_srtp_supported()
{
#if HAVE_OPENSSL_DTLS_SRTP
- return tsk_true;
+ return tsk_true;
#else
- return tsk_false;
+ return tsk_false;
#endif
}
tsk_bool_t tnet_dtls_is_supported()
{
#if HAVE_OPENSSL_DTLS
- return tsk_true;
+ return tsk_true;
#else
- return tsk_false;
+ return tsk_false;
#endif
}
@@ -105,298 +104,304 @@ static tsk_bool_t _tnet_dtls_is_fingerprint_matching(X509* cert, tnet_fingerprin
static int _tnet_dtls_verify_cert(int preverify_ok, X509_STORE_CTX *ctx)
{
- SSL *ssl;
- tnet_dtls_socket_t* socket;
-
- TSK_DEBUG_INFO("_tnet_dtls_verify_cert");
-
- ssl = X509_STORE_CTX_get_app_data(ctx);
- socket = (tnet_dtls_socket_t*)SSL_get_app_data(ssl);
- if (!ssl || !socket){
- TSK_DEBUG_ERROR("Not expected");
- return 0;
- }
- tsk_safeobj_lock(socket);
- if (_tnet_dtls_is_fingerprint_matching(ctx->cert, &socket->remote.fp, socket->remote.hash) == tsk_false) {
- TSK_DEBUG_ERROR("Failed to match fingerprint");
- tsk_safeobj_unlock(socket);
- return 0;
- }
- tsk_safeobj_unlock(socket);
- return 1;
+ SSL *ssl;
+ tnet_dtls_socket_t* socket;
+
+ TSK_DEBUG_INFO("_tnet_dtls_verify_cert");
+
+ ssl = X509_STORE_CTX_get_app_data(ctx);
+ socket = (tnet_dtls_socket_t*)SSL_get_app_data(ssl);
+ if (!ssl || !socket) {
+ TSK_DEBUG_ERROR("Not expected");
+ return 0;
+ }
+ tsk_safeobj_lock(socket);
+ if (_tnet_dtls_is_fingerprint_matching(ctx->cert, &socket->remote.fp, socket->remote.hash) == tsk_false) {
+ TSK_DEBUG_ERROR("Failed to match fingerprint");
+ tsk_safeobj_unlock(socket);
+ return 0;
+ }
+ tsk_safeobj_unlock(socket);
+ return 1;
}
static const EVP_MD *_tnet_dtls_get_hash_evp(tnet_dtls_hash_type_t hash)
{
- switch (hash){
- case tnet_dtls_hash_type_md5: return EVP_md5();
- case tnet_dtls_hash_type_sha1: return EVP_sha1();
- case tnet_dtls_hash_type_sha256: return EVP_sha256();
- case tnet_dtls_hash_type_sha512: return EVP_sha512();
- default: TSK_DEBUG_ERROR("Invalid parameter: %d not valid as hash type", hash); return tsk_null;
- }
+ switch (hash) {
+ case tnet_dtls_hash_type_md5:
+ return EVP_md5();
+ case tnet_dtls_hash_type_sha1:
+ return EVP_sha1();
+ case tnet_dtls_hash_type_sha256:
+ return EVP_sha256();
+ case tnet_dtls_hash_type_sha512:
+ return EVP_sha512();
+ default:
+ TSK_DEBUG_ERROR("Invalid parameter: %d not valid as hash type", hash);
+ return tsk_null;
+ }
}
static int _tnet_dtls_get_fingerprint(X509* cert, const EVP_MD *evp, tnet_fingerprint_t* fingerprint)
{
- if (!cert || !evp || !fingerprint){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- else{
- unsigned len = 0, i, j;
- tnet_fingerprint_t fp;
-
- if (X509_digest(cert, evp, fp, &len) != 1 || len <= 0){
- TSK_DEBUG_ERROR("X509_digest() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- return -2;
- }
- for (i = 0, j = 0; i < len; ++i, j += 3){
- sprintf((char*)&(*fingerprint)[j], (i == (len - 1)) ? "%.2X" : "%.2X:", fp[i]);
- }
- (*fingerprint)[len * 3] = '\0';
- return 0;
- }
+ if (!cert || !evp || !fingerprint) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ else {
+ unsigned len = 0, i, j;
+ tnet_fingerprint_t fp;
+
+ if (X509_digest(cert, evp, fp, &len) != 1 || len <= 0) {
+ TSK_DEBUG_ERROR("X509_digest() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ return -2;
+ }
+ for (i = 0, j = 0; i < len; ++i, j += 3) {
+ sprintf((char*)&(*fingerprint)[j], (i == (len - 1)) ? "%.2X" : "%.2X:", fp[i]);
+ }
+ (*fingerprint)[len * 3] = '\0';
+ return 0;
+ }
}
static tsk_bool_t _tnet_dtls_is_fingerprint_matching(X509* cert, tnet_fingerprint_t* fingerprint, tnet_dtls_hash_type_t hash)
{
- const EVP_MD* evp;
- tnet_fingerprint_t fp;
- int ret;
-
- if (!cert || !fingerprint){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_false;
- }
-
- if (!(evp = _tnet_dtls_get_hash_evp(hash))){
- return tsk_false;
- }
- if ((ret = _tnet_dtls_get_fingerprint(cert, evp, &fp))){
- return tsk_false;
- }
- if (!tsk_striequals(fp, fingerprint)){
- TSK_DEBUG_ERROR("DTLS certificate fingerprints mismatch: [%s]#[%s]", fp, *fingerprint);
- return tsk_false;
- }
- return tsk_true;
+ const EVP_MD* evp;
+ tnet_fingerprint_t fp;
+ int ret;
+
+ if (!cert || !fingerprint) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_false;
+ }
+
+ if (!(evp = _tnet_dtls_get_hash_evp(hash))) {
+ return tsk_false;
+ }
+ if ((ret = _tnet_dtls_get_fingerprint(cert, evp, &fp))) {
+ return tsk_false;
+ }
+ if (!tsk_striequals(fp, fingerprint)) {
+ TSK_DEBUG_ERROR("DTLS certificate fingerprints mismatch: [%s]#[%s]", fp, *fingerprint);
+ return tsk_false;
+ }
+ return tsk_true;
}
static tsk_bool_t _tnet_dtls_socket_is_remote_cert_fp_match(tnet_dtls_socket_t* socket)
{
- if (!socket){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_false;
- }
- else if (socket->verify_peer){
- X509* cert;
-
- if (!(cert = SSL_get_peer_certificate(socket->ssl))){
- if (socket->verify_peer){ // print error only if verify certs is enabled
- TSK_DEBUG_ERROR("Failed to get peer certificate [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- }
- return tsk_false;
- }
- if (!_tnet_dtls_is_fingerprint_matching(cert, &socket->remote.fp, socket->remote.hash)){
- X509_free(cert);
- return tsk_false;
- }
- X509_free(cert);
-
- if (SSL_get_verify_result(socket->ssl) != X509_V_OK){
- TSK_DEBUG_ERROR("SSL_get_verify_result()#X509_V_OK [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- return tsk_false;
- }
- }
-
- return tsk_true;
+ if (!socket) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_false;
+ }
+ else if (socket->verify_peer) {
+ X509* cert;
+
+ if (!(cert = SSL_get_peer_certificate(socket->ssl))) {
+ if (socket->verify_peer) { // print error only if verify certs is enabled
+ TSK_DEBUG_ERROR("Failed to get peer certificate [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ }
+ return tsk_false;
+ }
+ if (!_tnet_dtls_is_fingerprint_matching(cert, &socket->remote.fp, socket->remote.hash)) {
+ X509_free(cert);
+ return tsk_false;
+ }
+ X509_free(cert);
+
+ if (SSL_get_verify_result(socket->ssl) != X509_V_OK) {
+ TSK_DEBUG_ERROR("SSL_get_verify_result()#X509_V_OK [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ return tsk_false;
+ }
+ }
+
+ return tsk_true;
}
#endif /* HAVE_OPENSSL */
tnet_dtls_hash_type_t tnet_dtls_get_hash_from_string(const char* hash)
{
- if (hash){
- int32_t i;
- for (i = 0; i < TNET_DTLS_HASH_TYPE_MAX; ++i){
- if (tsk_striequals(TNET_DTLS_HASH_NAMES[i], hash)){
- return (tnet_dtls_hash_type_t)i;
- }
- }
- }
- return tnet_dtls_hash_type_none;
+ if (hash) {
+ int32_t i;
+ for (i = 0; i < TNET_DTLS_HASH_TYPE_MAX; ++i) {
+ if (tsk_striequals(TNET_DTLS_HASH_NAMES[i], hash)) {
+ return (tnet_dtls_hash_type_t)i;
+ }
+ }
+ }
+ return tnet_dtls_hash_type_none;
}
tnet_dtls_setup_t tnet_dtls_get_setup_from_string(const char* setup)
{
- if (setup){
- int32_t i;
- for (i = 0; i < TNET_DTLS_SETUP_MAX; ++i){
- if (tsk_striequals(TNET_DTLS_SETUP_NAMES[i], setup)){
- return (tnet_dtls_setup_t)i;
- }
- }
- }
- return tnet_dtls_setup_none;
+ if (setup) {
+ int32_t i;
+ for (i = 0; i < TNET_DTLS_SETUP_MAX; ++i) {
+ if (tsk_striequals(TNET_DTLS_SETUP_NAMES[i], setup)) {
+ return (tnet_dtls_setup_t)i;
+ }
+ }
+ }
+ return tnet_dtls_setup_none;
}
int tnet_dtls_get_fingerprint(const char* certfile, tnet_fingerprint_t* fingerprint, tnet_dtls_hash_type_t hash)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
- TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
- return -200;
+ TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
+ return -200;
#else
- {
- X509* x509;
- BIO* bio;
- int ret = 0;
- const EVP_MD *evp;
-
- if (tsk_strnullORempty(certfile) || !fingerprint){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if (!(evp = _tnet_dtls_get_hash_evp(hash))){
- return -1;
- }
-
- x509 = tsk_null;
- bio = tsk_null;
-
- if (!(bio = BIO_new(BIO_s_file()))){
- TSK_DEBUG_ERROR("BIO_new(BIO_s_file()) failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- ret = -3;
- goto bail;
- }
- if (BIO_read_filename(bio, certfile) != 1){
- TSK_DEBUG_ERROR("BIO_read_filename(%s) failed [%s]", certfile, ERR_error_string(ERR_get_error(), tsk_null));
- ret = -4;
- goto bail;
- }
- if (!(x509 = PEM_read_bio_X509(bio, tsk_null, 0, tsk_null))){
- TSK_DEBUG_ERROR("PEM_read_bio() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- ret = -5;
- goto bail;
- }
- if ((ret = _tnet_dtls_get_fingerprint(x509, evp, fingerprint))){
- goto bail;
- }
-
- bail:
- if (bio){
- BIO_free_all(bio);
- }
- return ret;
- }
+ {
+ X509* x509;
+ BIO* bio;
+ int ret = 0;
+ const EVP_MD *evp;
+
+ if (tsk_strnullORempty(certfile) || !fingerprint) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if (!(evp = _tnet_dtls_get_hash_evp(hash))) {
+ return -1;
+ }
+
+ x509 = tsk_null;
+ bio = tsk_null;
+
+ if (!(bio = BIO_new(BIO_s_file()))) {
+ TSK_DEBUG_ERROR("BIO_new(BIO_s_file()) failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ ret = -3;
+ goto bail;
+ }
+ if (BIO_read_filename(bio, certfile) != 1) {
+ TSK_DEBUG_ERROR("BIO_read_filename(%s) failed [%s]", certfile, ERR_error_string(ERR_get_error(), tsk_null));
+ ret = -4;
+ goto bail;
+ }
+ if (!(x509 = PEM_read_bio_X509(bio, tsk_null, 0, tsk_null))) {
+ TSK_DEBUG_ERROR("PEM_read_bio() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ ret = -5;
+ goto bail;
+ }
+ if ((ret = _tnet_dtls_get_fingerprint(x509, evp, fingerprint))) {
+ goto bail;
+ }
+
+bail:
+ if (bio) {
+ BIO_free_all(bio);
+ }
+ return ret;
+ }
#endif
}
tnet_dtls_socket_handle_t* tnet_dtls_socket_create(struct tnet_socket_s* wrapped_sock, struct ssl_ctx_st* ssl_ctx)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
- TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
- return tsk_null;
+ TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
+ return tsk_null;
#else
- tnet_dtls_socket_t* socket;
-
- if (!wrapped_sock || !ssl_ctx){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
- if ((socket = tsk_object_new(tnet_dtls_socket_def_t))) {
- EC_KEY* ecdh;
- const tsk_bool_t set_mtu = TNET_SOCKET_TYPE_IS_DGRAM(wrapped_sock->type) || 1; //!\ This is required even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
- socket->wrapped_sock = tsk_object_ref(wrapped_sock);
- if (!(socket->ssl = SSL_new(ssl_ctx))) {
- TSK_DEBUG_ERROR("SSL_new(CTX) failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- TSK_OBJECT_SAFE_FREE(socket);
- return tsk_null;
- }
- if (set_mtu) {
- SSL_set_options(socket->ssl, SSL_OP_NO_QUERY_MTU);
- SSL_set_mtu(socket->ssl, TNET_DTLS_MTU - 28);
- socket->ssl->d1->mtu = TNET_DTLS_MTU - 28;
- }
- if (!(socket->rbio = BIO_new(BIO_s_mem())) || !(socket->wbio = BIO_new(BIO_s_mem()))){
- TSK_DEBUG_ERROR("BIO_new_socket(%d) failed [%s]", socket->wrapped_sock->fd, ERR_error_string(ERR_get_error(), tsk_null));
- if (socket->rbio){
- BIO_free(socket->rbio);
- }
- if (socket->wbio){
- BIO_free(socket->wbio);
- }
- TSK_OBJECT_SAFE_FREE(socket);
- return tsk_null;
- }
- BIO_set_mem_eof_return(socket->rbio, -1);
- BIO_set_mem_eof_return(socket->wbio, -1);
- SSL_set_bio(socket->ssl, socket->rbio, socket->wbio);
- SSL_set_mode(socket->ssl, SSL_MODE_AUTO_RETRY);
- SSL_set_read_ahead(socket->ssl, 1);
- // https://groups.google.com/forum/#!topic/doubango/Oo0t1e3tlL8
- if ((ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1))) {
- SSL_set_options(socket->ssl, SSL_OP_SINGLE_ECDH_USE);
- SSL_set_tmp_ecdh(socket->ssl, ecdh);
- EC_KEY_free(ecdh);
- }
-
- if (set_mtu) {
- BIO_ctrl(SSL_get_wbio(socket->ssl), BIO_CTRL_DGRAM_SET_MTU, TNET_DTLS_MTU - 28, NULL);
- }
-
- if ((socket->verify_peer = (SSL_CTX_get_verify_mode(ssl_ctx) != SSL_VERIFY_NONE))){
- TSK_DEBUG_INFO("SSL cert verify: ON");
- socket->verify_peer = tsk_true;
- SSL_set_verify(socket->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), _tnet_dtls_verify_cert);
- }
- else {
- TSK_DEBUG_ERROR("Verity not enabled");
- }
-
- SSL_set_app_data(socket->ssl, socket);
- }
- return socket;
+ tnet_dtls_socket_t* socket;
+
+ if (!wrapped_sock || !ssl_ctx) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+ if ((socket = tsk_object_new(tnet_dtls_socket_def_t))) {
+ EC_KEY* ecdh;
+ const tsk_bool_t set_mtu = TNET_SOCKET_TYPE_IS_DGRAM(wrapped_sock->type) || 1; //!\ This is required even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
+ socket->wrapped_sock = tsk_object_ref(wrapped_sock);
+ if (!(socket->ssl = SSL_new(ssl_ctx))) {
+ TSK_DEBUG_ERROR("SSL_new(CTX) failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ TSK_OBJECT_SAFE_FREE(socket);
+ return tsk_null;
+ }
+ if (set_mtu) {
+ SSL_set_options(socket->ssl, SSL_OP_NO_QUERY_MTU);
+ SSL_set_mtu(socket->ssl, TNET_DTLS_MTU - 28);
+ socket->ssl->d1->mtu = TNET_DTLS_MTU - 28;
+ }
+ if (!(socket->rbio = BIO_new(BIO_s_mem())) || !(socket->wbio = BIO_new(BIO_s_mem()))) {
+ TSK_DEBUG_ERROR("BIO_new_socket(%d) failed [%s]", socket->wrapped_sock->fd, ERR_error_string(ERR_get_error(), tsk_null));
+ if (socket->rbio) {
+ BIO_free(socket->rbio);
+ }
+ if (socket->wbio) {
+ BIO_free(socket->wbio);
+ }
+ TSK_OBJECT_SAFE_FREE(socket);
+ return tsk_null;
+ }
+ BIO_set_mem_eof_return(socket->rbio, -1);
+ BIO_set_mem_eof_return(socket->wbio, -1);
+ SSL_set_bio(socket->ssl, socket->rbio, socket->wbio);
+ SSL_set_mode(socket->ssl, SSL_MODE_AUTO_RETRY);
+ SSL_set_read_ahead(socket->ssl, 1);
+ // https://groups.google.com/forum/#!topic/doubango/Oo0t1e3tlL8
+ if ((ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1))) {
+ SSL_set_options(socket->ssl, SSL_OP_SINGLE_ECDH_USE);
+ SSL_set_tmp_ecdh(socket->ssl, ecdh);
+ EC_KEY_free(ecdh);
+ }
+
+ if (set_mtu) {
+ BIO_ctrl(SSL_get_wbio(socket->ssl), BIO_CTRL_DGRAM_SET_MTU, TNET_DTLS_MTU - 28, NULL);
+ }
+
+ if ((socket->verify_peer = (SSL_CTX_get_verify_mode(ssl_ctx) != SSL_VERIFY_NONE))) {
+ TSK_DEBUG_INFO("SSL cert verify: ON");
+ socket->verify_peer = tsk_true;
+ SSL_set_verify(socket->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), _tnet_dtls_verify_cert);
+ }
+ else {
+ TSK_DEBUG_ERROR("Verity not enabled");
+ }
+
+ SSL_set_app_data(socket->ssl, socket);
+ }
+ return socket;
#endif
}
tnet_fd_t tnet_dtls_socket_get_fd(const tnet_dtls_socket_handle_t* handle)
{
- return handle ? ((const tnet_dtls_socket_t*)handle)->wrapped_sock->fd : TNET_INVALID_FD;
+ return handle ? ((const tnet_dtls_socket_t*)handle)->wrapped_sock->fd : TNET_INVALID_FD;
}
const struct sockaddr_storage* tnet_dtls_socket_get_remote_addr(const tnet_dtls_socket_handle_t* handle)
{
- return handle ? &((const tnet_dtls_socket_t*)handle)->remote.addr : tsk_null;
+ return handle ? &((const tnet_dtls_socket_t*)handle)->remote.addr : tsk_null;
}
int tnet_dtls_socket_set_callback(tnet_dtls_socket_handle_t* handle, const void* usrdata, tnet_dtls_socket_cb_f func)
{
- tnet_dtls_socket_t* socket = handle;
+ tnet_dtls_socket_t* socket = handle;
- if (!socket){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!socket) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- socket->cb.usrdata = usrdata;
- socket->cb.func = func;
- return 0;
+ socket->cb.usrdata = usrdata;
+ socket->cb.func = func;
+ return 0;
}
int tnet_dtls_socket_set_remote_fingerprint(tnet_dtls_socket_handle_t* handle, const tnet_fingerprint_t* fingerprint, tnet_dtls_hash_type_t hash)
{
- tnet_dtls_socket_t* socket = handle;
+ tnet_dtls_socket_t* socket = handle;
- if (!socket || !fingerprint){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!socket || !fingerprint) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- memcpy(socket->remote.fp, &(*fingerprint)[0], sizeof(tnet_fingerprint_t));
- socket->remote.hash = hash;
- return 0;
+ memcpy(socket->remote.fp, &(*fingerprint)[0], sizeof(tnet_fingerprint_t));
+ socket->remote.hash = hash;
+ return 0;
}
/*
@@ -405,267 +410,267 @@ rfc5764: 4.1. The use_srtp Extension
int tnet_dtls_socket_use_srtp(tnet_dtls_socket_handle_t*handle)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS || !HAVE_OPENSSL_DTLS_SRTP
- TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
- return -200;
+ TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
+ return -200;
#else
- tnet_dtls_socket_t* socket = handle;
- if (!socket){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if ((socket->use_srtp = tsk_true)){
- if (!socket->verify_peer){
- socket->verify_peer = tsk_true; // DTLS-SRTP requires certtificates
- SSL_set_verify(socket->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), _tnet_dtls_verify_cert);
- }
- }
- return 0;
+ tnet_dtls_socket_t* socket = handle;
+ if (!socket) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if ((socket->use_srtp = tsk_true)) {
+ if (!socket->verify_peer) {
+ socket->verify_peer = tsk_true; // DTLS-SRTP requires certtificates
+ SSL_set_verify(socket->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), _tnet_dtls_verify_cert);
+ }
+ }
+ return 0;
#endif
}
int tnet_dtls_socket_set_setup(tnet_dtls_socket_handle_t* handle, tnet_dtls_setup_t setup)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
- TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
- return -200;
+ TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
+ return -200;
#else
- tnet_dtls_socket_t* socket = handle;
- if (!socket){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- switch ((socket->setup = setup)){
- case tnet_dtls_setup_passive:
- SSL_set_accept_state(socket->ssl);
- break;
- case tnet_dtls_setup_active:
- case tnet_dtls_setup_actpass:
- case tnet_dtls_setup_none:
- if (setup != tnet_dtls_setup_active){
- TSK_DEBUG_WARN("using setup=%s is not a good idea", TNET_DTLS_SETUP_NAMES[setup]);
- }
- SSL_set_connect_state(socket->ssl);
- break;
- default:
- TSK_DEBUG_ERROR("%d not valid value for DTLS setup", (int32_t)setup);
- break;
- }
- return 0;
+ tnet_dtls_socket_t* socket = handle;
+ if (!socket) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ switch ((socket->setup = setup)) {
+ case tnet_dtls_setup_passive:
+ SSL_set_accept_state(socket->ssl);
+ break;
+ case tnet_dtls_setup_active:
+ case tnet_dtls_setup_actpass:
+ case tnet_dtls_setup_none:
+ if (setup != tnet_dtls_setup_active) {
+ TSK_DEBUG_WARN("using setup=%s is not a good idea", TNET_DTLS_SETUP_NAMES[setup]);
+ }
+ SSL_set_connect_state(socket->ssl);
+ break;
+ default:
+ TSK_DEBUG_ERROR("%d not valid value for DTLS setup", (int32_t)setup);
+ break;
+ }
+ return 0;
#endif
}
int tnet_dtls_socket_set_store_handshakingdata(tnet_dtls_socket_handle_t* handle, tsk_bool_t handshake_storedata)
{
- if (!handle) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- ((tnet_dtls_socket_t*)handle)->handshake_storedata = handshake_storedata;
- return 0;
+ if (!handle) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ ((tnet_dtls_socket_t*)handle)->handshake_storedata = handshake_storedata;
+ return 0;
}
int tnet_dtls_socket_get_handshakingdata(tnet_dtls_socket_handle_t* handle, const void** data, tsk_size_t *size)
{
- if (!handle || !data || !size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *data = ((tnet_dtls_socket_t*)handle)->handshake_data.ptr;
- *size = ((tnet_dtls_socket_t*)handle)->handshake_data.count;
- return 0;
+ if (!handle || !data || !size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *data = ((tnet_dtls_socket_t*)handle)->handshake_data.ptr;
+ *size = ((tnet_dtls_socket_t*)handle)->handshake_data.count;
+ return 0;
}
// This function returns first DTLS record. It's useful to send handshaking data by records to avoid IP fragmentation
int tnet_dtls_socket_get_record_first(const void* records, tsk_size_t records_size, const void** record, tsk_size_t* size)
{
- /* https://tools.ietf.org/html/rfc6347#section-3.2.3
- TLS and DTLS handshake messages can be quite large(in theory up to
- 2 ^ 24 - 1 bytes, in practice many kilobytes).By contrast, UDP
- datagrams are often limited to <1500 bytes if IP fragmentation is not
- desired.In order to compensate for this limitation, each DTLS
- handshake message may be fragmented over several DTLS records, each
- of which is intended to fit in a single IP datagram.Each DTLS
- handshake message contains both a fragment offset and a fragment
- length.Thus, a recipient in possession of all bytes of a handshake
- message can reassemble the original unfragmented message. */
- // 4.1. Record Layer - https://tools.ietf.org/html/rfc6347#section-4.1
+ /* https://tools.ietf.org/html/rfc6347#section-3.2.3
+ TLS and DTLS handshake messages can be quite large(in theory up to
+ 2 ^ 24 - 1 bytes, in practice many kilobytes).By contrast, UDP
+ datagrams are often limited to <1500 bytes if IP fragmentation is not
+ desired.In order to compensate for this limitation, each DTLS
+ handshake message may be fragmented over several DTLS records, each
+ of which is intended to fit in a single IP datagram.Each DTLS
+ handshake message contains both a fragment offset and a fragment
+ length.Thus, a recipient in possession of all bytes of a handshake
+ message can reassemble the original unfragmented message. */
+ // 4.1. Record Layer - https://tools.ietf.org/html/rfc6347#section-4.1
#define kDTLSv1RecordHdrStartIndex 11
#define kDTLSv1RecordHdrLengthFieldLen 2 // uint16
#define kDTLSv1RecordHdrLen (kDTLSv1RecordHdrStartIndex + kDTLSv1RecordHdrLengthFieldLen)
-
- const uint8_t* pc_records;
- tsk_size_t record_length;
- if (!records || records_size < kDTLSv1RecordHdrLen || !record || !size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- pc_records = (const uint8_t*)records;
- record_length = ((pc_records[kDTLSv1RecordHdrStartIndex] << 8) & 0xFF00) | (pc_records[kDTLSv1RecordHdrStartIndex + 1] & 0xFF);
- *record = records;
- *size = kDTLSv1RecordHdrLen + record_length;
- if ((*size) > TNET_DTLS_MTU) {
- TSK_DEBUG_WARN("DTLS record length(%u) > MTU(%u)", (unsigned)(*size), TNET_DTLS_MTU);
- }
-
- return 0;
+
+ const uint8_t* pc_records;
+ tsk_size_t record_length;
+ if (!records || records_size < kDTLSv1RecordHdrLen || !record || !size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ pc_records = (const uint8_t*)records;
+ record_length = ((pc_records[kDTLSv1RecordHdrStartIndex] << 8) & 0xFF00) | (pc_records[kDTLSv1RecordHdrStartIndex + 1] & 0xFF);
+ *record = records;
+ *size = kDTLSv1RecordHdrLen + record_length;
+ if ((*size) > TNET_DTLS_MTU) {
+ TSK_DEBUG_WARN("DTLS record length(%u) > MTU(%u)", (unsigned)(*size), TNET_DTLS_MTU);
+ }
+
+ return 0;
}
tsk_bool_t tnet_dtls_socket_is_remote_cert_fp_match(tnet_dtls_socket_handle_t* handle)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
- TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
- return -1;
+ TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
+ return -1;
#else
- return _tnet_dtls_socket_is_remote_cert_fp_match((tnet_dtls_socket_t*)handle);
+ return _tnet_dtls_socket_is_remote_cert_fp_match((tnet_dtls_socket_t*)handle);
#endif
}
int tnet_dtls_socket_do_handshake(tnet_dtls_socket_handle_t* handle, const struct sockaddr_storage* remote_addr)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
- TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
- return -1;
+ TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
+ return -1;
#else
- tnet_dtls_socket_t *socket = handle;
- int ret = 0, len;
- void* out_data;
-
- if (!socket) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- tsk_safeobj_lock(socket);
-
- // update remote address even if handshaking is completed
- if (remote_addr) {
- socket->remote.addr = *remote_addr;
- }
-
- if (socket->handshake_completed) {
- TSK_DEBUG_INFO("Handshake completed");
- ret = 0;
- goto bail;
- }
-
- if (!socket->handshake_started) {
- if ((ret = SSL_do_handshake(socket->ssl)) != 1) {
- switch ((ret = SSL_get_error(socket->ssl, ret))) {
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_NONE:
- break;
- default:
- TSK_DEBUG_ERROR("DTLS handshake failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- _tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_failed);
- ret = -2;
- goto bail;
- }
- }
- socket->handshake_started = (ret == SSL_ERROR_NONE); // TODO: reset for renegotiation
- }
-
- if ((len = (int)BIO_get_mem_data(socket->wbio, &out_data)) > 0 && out_data) {
- if (socket->handshake_storedata) { // e.g. when TURN is enabled we have to query handshaking data and sent it via the negotiated channel
- if ((int)socket->handshake_data.size < len) {
- if (!(socket->handshake_data.ptr = tsk_realloc(socket->handshake_data.ptr, len))) {
- socket->handshake_data.size = 0;
- socket->handshake_data.count = 0;
- ret = -5;
- goto bail;
- }
- socket->handshake_data.size = len;
- }
- socket->handshake_data.count = len;
- memcpy(socket->handshake_data.ptr, out_data, len);
- }
- else {
- int sentlen = 0;
- tnet_port_t port;
- tnet_ip_t ip;
- tsk_bool_t is_dgram = TNET_SOCKET_TYPE_IS_DGRAM(socket->wrapped_sock->type);
- const uint8_t *record_ptr, *records_ptr = out_data;
- tsk_size_t record_size;
- int records_len = len;
-
- tnet_get_sockip_n_port((const struct sockaddr *)&socket->remote.addr, &ip, &port);
- TSK_DEBUG_INFO("DTLS data handshake to send with len = %d, from(%.*s/%d) to(%.*s/%d)", len, (int)sizeof(socket->wrapped_sock->ip), socket->wrapped_sock->ip, socket->wrapped_sock->port, (int)sizeof(ip), ip, port);
-
- //!\ IP fragmentation issues must be avoided even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
- while (records_len > 0 && (ret = tnet_dtls_socket_get_record_first(records_ptr, (tsk_size_t)records_len, (const void**)&record_ptr, &record_size)) == 0) {
- if (is_dgram) {
- sentlen += tnet_sockfd_sendto(socket->wrapped_sock->fd, (const struct sockaddr *)&socket->remote.addr, record_ptr, record_size);
- }
- else {
- sentlen += tnet_socket_send_stream(socket->wrapped_sock, record_ptr, record_size);
- }
- records_len -= (int)record_size;
- records_ptr += record_size;
- }
- TSK_DEBUG_INFO("DTLS data handshake sent len = %d", sentlen);
- }
- }
-
- BIO_reset(socket->rbio);
- BIO_reset(socket->wbio);
-
- if ((socket->handshake_completed = SSL_is_init_finished(socket->ssl))) {
- TSK_DEBUG_INFO("DTLS handshake completed");
+ tnet_dtls_socket_t *socket = handle;
+ int ret = 0, len;
+ void* out_data;
+
+ if (!socket) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ tsk_safeobj_lock(socket);
+
+ // update remote address even if handshaking is completed
+ if (remote_addr) {
+ socket->remote.addr = *remote_addr;
+ }
+
+ if (socket->handshake_completed) {
+ TSK_DEBUG_INFO("Handshake completed");
+ ret = 0;
+ goto bail;
+ }
+
+ if (!socket->handshake_started) {
+ if ((ret = SSL_do_handshake(socket->ssl)) != 1) {
+ switch ((ret = SSL_get_error(socket->ssl, ret))) {
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_NONE:
+ break;
+ default:
+ TSK_DEBUG_ERROR("DTLS handshake failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ _tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_failed);
+ ret = -2;
+ goto bail;
+ }
+ }
+ socket->handshake_started = (ret == SSL_ERROR_NONE); // TODO: reset for renegotiation
+ }
+
+ if ((len = (int)BIO_get_mem_data(socket->wbio, &out_data)) > 0 && out_data) {
+ if (socket->handshake_storedata) { // e.g. when TURN is enabled we have to query handshaking data and sent it via the negotiated channel
+ if ((int)socket->handshake_data.size < len) {
+ if (!(socket->handshake_data.ptr = tsk_realloc(socket->handshake_data.ptr, len))) {
+ socket->handshake_data.size = 0;
+ socket->handshake_data.count = 0;
+ ret = -5;
+ goto bail;
+ }
+ socket->handshake_data.size = len;
+ }
+ socket->handshake_data.count = len;
+ memcpy(socket->handshake_data.ptr, out_data, len);
+ }
+ else {
+ int sentlen = 0;
+ tnet_port_t port;
+ tnet_ip_t ip;
+ tsk_bool_t is_dgram = TNET_SOCKET_TYPE_IS_DGRAM(socket->wrapped_sock->type);
+ const uint8_t *record_ptr, *records_ptr = out_data;
+ tsk_size_t record_size;
+ int records_len = len;
+
+ tnet_get_sockip_n_port((const struct sockaddr *)&socket->remote.addr, &ip, &port);
+ TSK_DEBUG_INFO("DTLS data handshake to send with len = %d, from(%.*s/%d) to(%.*s/%d)", len, (int)sizeof(socket->wrapped_sock->ip), socket->wrapped_sock->ip, socket->wrapped_sock->port, (int)sizeof(ip), ip, port);
+
+ //!\ IP fragmentation issues must be avoided even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
+ while (records_len > 0 && (ret = tnet_dtls_socket_get_record_first(records_ptr, (tsk_size_t)records_len, (const void**)&record_ptr, &record_size)) == 0) {
+ if (is_dgram) {
+ sentlen += tnet_sockfd_sendto(socket->wrapped_sock->fd, (const struct sockaddr *)&socket->remote.addr, record_ptr, record_size);
+ }
+ else {
+ sentlen += tnet_socket_send_stream(socket->wrapped_sock, record_ptr, record_size);
+ }
+ records_len -= (int)record_size;
+ records_ptr += record_size;
+ }
+ TSK_DEBUG_INFO("DTLS data handshake sent len = %d", sentlen);
+ }
+ }
+
+ BIO_reset(socket->rbio);
+ BIO_reset(socket->wbio);
+
+ if ((socket->handshake_completed = SSL_is_init_finished(socket->ssl))) {
+ TSK_DEBUG_INFO("DTLS handshake completed");
#if HAVE_OPENSSL_DTLS_SRTP
- if (socket->use_srtp){
+ if (socket->use_srtp) {
#if !defined(SRTP_MAX_KEY_LEN)
# define cipher_key_length (128 >> 3) // rfc5764 4.1.2. SRTP Protection Profiles
# define cipher_salt_length (112 >> 3) // rfc5764 4.1.2. SRTP Protection Profiles
- // "cipher_key_length" is also equal to srtp_profile_get_master_key_length(srtp_profile_aes128_cm_sha1_80)
- // "cipher_salt_length" is also srtp_profile_get_master_salt_length(srtp_profile_aes128_cm_sha1_80)
+ // "cipher_key_length" is also equal to srtp_profile_get_master_key_length(srtp_profile_aes128_cm_sha1_80)
+ // "cipher_salt_length" is also srtp_profile_get_master_salt_length(srtp_profile_aes128_cm_sha1_80)
# define SRTP_MAX_KEY_LEN (cipher_key_length + cipher_salt_length)
#endif /* SRTP_MAX_KEY_LEN */
#define EXTRACTOR_dtls_srtp_text "EXTRACTOR-dtls_srtp"
#define EXTRACTOR_dtls_srtp_text_len 19
- uint8_t keying_material[SRTP_MAX_KEY_LEN << 1];
- static const tsk_size_t keying_material_size = sizeof(keying_material);
- /*if(socket->use_srtp)*/{
- SRTP_PROTECTION_PROFILE *p = SSL_get_selected_srtp_profile(socket->ssl);
- if (!p) {
- TSK_DEBUG_ERROR("SSL_get_selected_srtp_profile() returned null [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- ret = -2;
- goto bail;
- }
- // alert user
- _tnet_dtls_socket_raise_event(socket, tnet_dtls_socket_event_type_dtls_srtp_profile_selected, p->name, tsk_strlen(p->name));
-
- memset(keying_material, 0, sizeof(keying_material));
-
- // rfc5764 - 4.2. Key Derivation
- ret = SSL_export_keying_material(socket->ssl, keying_material, sizeof(keying_material), EXTRACTOR_dtls_srtp_text, EXTRACTOR_dtls_srtp_text_len, tsk_null, 0, 0);
- if (ret != 1) {
- // alert listener
- _tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_error);
- TSK_DEBUG_ERROR("SSL_export_keying_material() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- ret = -2;
- goto bail;
- }
- }
- // alert listener
- _tnet_dtls_socket_raise_event(socket, tnet_dtls_socket_event_type_dtls_srtp_data, keying_material, keying_material_size);
- }
+ uint8_t keying_material[SRTP_MAX_KEY_LEN << 1];
+ static const tsk_size_t keying_material_size = sizeof(keying_material);
+ /*if(socket->use_srtp)*/{
+ SRTP_PROTECTION_PROFILE *p = SSL_get_selected_srtp_profile(socket->ssl);
+ if (!p) {
+ TSK_DEBUG_ERROR("SSL_get_selected_srtp_profile() returned null [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ ret = -2;
+ goto bail;
+ }
+ // alert user
+ _tnet_dtls_socket_raise_event(socket, tnet_dtls_socket_event_type_dtls_srtp_profile_selected, p->name, tsk_strlen(p->name));
+
+ memset(keying_material, 0, sizeof(keying_material));
+
+ // rfc5764 - 4.2. Key Derivation
+ ret = SSL_export_keying_material(socket->ssl, keying_material, sizeof(keying_material), EXTRACTOR_dtls_srtp_text, EXTRACTOR_dtls_srtp_text_len, tsk_null, 0, 0);
+ if (ret != 1) {
+ // alert listener
+ _tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_error);
+ TSK_DEBUG_ERROR("SSL_export_keying_material() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ ret = -2;
+ goto bail;
+ }
+ }
+ // alert listener
+ _tnet_dtls_socket_raise_event(socket, tnet_dtls_socket_event_type_dtls_srtp_data, keying_material, keying_material_size);
+ }
#endif /* HAVE_OPENSSL_DTLS_SRTP */
- _tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_succeed);
- }
- ret = 0; // clear "ret", error will directly jump to "bail:"
+ _tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_succeed);
+ }
+ ret = 0; // clear "ret", error will directly jump to "bail:"
bail:
- tsk_safeobj_unlock(socket);
- return ret;
+ tsk_safeobj_unlock(socket);
+ return ret;
#endif
}
tsk_bool_t tnet_dtls_socket_is_handshake_completed(const tnet_dtls_socket_handle_t* handle)
{
- return (handle && ((const tnet_dtls_socket_t *)handle)->handshake_completed);
+ return (handle && ((const tnet_dtls_socket_t *)handle)->handshake_completed);
}
/*
@@ -678,79 +683,79 @@ Handles DTLS data received over the network using standard functions (e.g. recvf
int tnet_dtls_socket_handle_incoming_data(tnet_dtls_socket_handle_t* handle, const void* data, tsk_size_t size)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
- TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
- return -200;
+ TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
+ return -200;
#else
- tnet_dtls_socket_t *socket = handle;
- int ret = 0;
-
- if (!socket || !data || !size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- tsk_safeobj_lock(socket);
-
- TSK_DEBUG_INFO("Receive DTLS data: %lu", (unsigned long)size);
-
- // BIO_reset(socket->rbio);
- // BIO_reset(socket->wbio);
-
- if (!socket->rbio || !socket->wbio) {
- TSK_DEBUG_ERROR("BIO not initialized yet");
- ret = -2;
- goto bail;
- }
-
- if ((ret = _tnet_dtls_socket_do_handshake(socket))) {
- goto bail;
- }
-
- if ((ret = BIO_write(socket->rbio, data, (int)size)) != size) {
- ret = SSL_get_error(socket->ssl, ret);
- TSK_DEBUG_ERROR("BIO_write(rbio, %lu) failed [%s]", (unsigned long)size, ERR_error_string(ERR_get_error(), tsk_null));
- ret = -1;
- goto bail;
- }
-
- /*if((ret = SSL_read(socket->ssl, (void*)data, size)) <= 0){
- switch((ret = SSL_get_error(socket->ssl, ret))){
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_NONE:
- break;
- default:
- {
- unsigned long sslErr = ERR_get_error();
- const uint8_t* pData = (const uint8_t*)data;
- TSK_DEBUG_ERROR("%lu = SSL_read(rbio, %u) failed [%s]", sslErr, size, ERR_error_string(ret, tsk_null));
- // try to understand what's going on
- // rfc6347 - 4.1. Record Layer
- // rfc6347 - 4.2.2. Handshake Message Format
- // rfc6347 - 4.3.2. Handshake Protocol
- if(size > 14 && pData[0] == 0x16){ // content-type=='Handshake'
- if(pData[13] == 0x01 && (socket->setup == tnet_dtls_setup_active || socket->setup == tnet_dtls_setup_actpass)){ // Handshake Type=='client Hello'
- TSK_DEBUG_INFO("DTLS engine was in client mode but we are receiving 'Client Hello' messages. This is a bug in the remote peer: Re-negotiating!");
- tnet_dtls_socket_set_setup(socket, tnet_dtls_setup_passive);
- break;
- }
- else if(pData[13] == 0x02 && (socket->setup == tnet_dtls_setup_passive || socket->setup == tnet_dtls_setup_actpass)){ // Handshake Type=='server Hello'
- TSK_DEBUG_INFO("DTLS engine was in server mode but we are receiving 'Server Hello' messages. This is a bug in the remote peer: Re-negotiating!");
- tnet_dtls_socket_set_setup(socket, tnet_dtls_setup_active);
- break;
- }
- }
- //return -1;
- break;
- }
- }
- }*/
-
- ret = _tnet_dtls_socket_do_handshake(socket);
+ tnet_dtls_socket_t *socket = handle;
+ int ret = 0;
+
+ if (!socket || !data || !size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ tsk_safeobj_lock(socket);
+
+ TSK_DEBUG_INFO("Receive DTLS data: %lu", (unsigned long)size);
+
+ // BIO_reset(socket->rbio);
+ // BIO_reset(socket->wbio);
+
+ if (!socket->rbio || !socket->wbio) {
+ TSK_DEBUG_ERROR("BIO not initialized yet");
+ ret = -2;
+ goto bail;
+ }
+
+ if ((ret = _tnet_dtls_socket_do_handshake(socket))) {
+ goto bail;
+ }
+
+ if ((ret = BIO_write(socket->rbio, data, (int)size)) != size) {
+ ret = SSL_get_error(socket->ssl, ret);
+ TSK_DEBUG_ERROR("BIO_write(rbio, %lu) failed [%s]", (unsigned long)size, ERR_error_string(ERR_get_error(), tsk_null));
+ ret = -1;
+ goto bail;
+ }
+
+ /*if((ret = SSL_read(socket->ssl, (void*)data, size)) <= 0){
+ switch((ret = SSL_get_error(socket->ssl, ret))){
+ case SSL_ERROR_WANT_READ:
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_NONE:
+ break;
+ default:
+ {
+ unsigned long sslErr = ERR_get_error();
+ const uint8_t* pData = (const uint8_t*)data;
+ TSK_DEBUG_ERROR("%lu = SSL_read(rbio, %u) failed [%s]", sslErr, size, ERR_error_string(ret, tsk_null));
+ // try to understand what's going on
+ // rfc6347 - 4.1. Record Layer
+ // rfc6347 - 4.2.2. Handshake Message Format
+ // rfc6347 - 4.3.2. Handshake Protocol
+ if(size > 14 && pData[0] == 0x16){ // content-type=='Handshake'
+ if(pData[13] == 0x01 && (socket->setup == tnet_dtls_setup_active || socket->setup == tnet_dtls_setup_actpass)){ // Handshake Type=='client Hello'
+ TSK_DEBUG_INFO("DTLS engine was in client mode but we are receiving 'Client Hello' messages. This is a bug in the remote peer: Re-negotiating!");
+ tnet_dtls_socket_set_setup(socket, tnet_dtls_setup_passive);
+ break;
+ }
+ else if(pData[13] == 0x02 && (socket->setup == tnet_dtls_setup_passive || socket->setup == tnet_dtls_setup_actpass)){ // Handshake Type=='server Hello'
+ TSK_DEBUG_INFO("DTLS engine was in server mode but we are receiving 'Server Hello' messages. This is a bug in the remote peer: Re-negotiating!");
+ tnet_dtls_socket_set_setup(socket, tnet_dtls_setup_active);
+ break;
+ }
+ }
+ //return -1;
+ break;
+ }
+ }
+ }*/
+
+ ret = _tnet_dtls_socket_do_handshake(socket);
bail:
- tsk_safeobj_unlock(socket);
- return ret;
+ tsk_safeobj_unlock(socket);
+ return ret;
#endif
}
@@ -760,47 +765,46 @@ bail:
//
static tsk_object_t* tnet_dtls_socket_ctor(tsk_object_t * self, va_list * app)
{
- tnet_dtls_socket_t *socket = self;
- if (socket){
- tsk_safeobj_init(socket);
- }
- return self;
+ tnet_dtls_socket_t *socket = self;
+ if (socket) {
+ tsk_safeobj_init(socket);
+ }
+ return self;
}
static tsk_object_t* tnet_dtls_socket_dtor(tsk_object_t * self)
{
- tnet_dtls_socket_t *socket = self;
- if (socket){
+ tnet_dtls_socket_t *socket = self;
+ if (socket) {
#if HAVE_OPENSSL
- if (socket->rbio) {
- //BIO_free(socket->rbio);
- socket->rbio = tsk_null;
- }
- if (socket->wbio) {
- //BIO_free(socket->wbio);
- socket->wbio = tsk_null;
- }
- if (socket->ssl) {
- SSL_shutdown(socket->ssl);
- // https://www.openssl.org/docs/crypto/BIO_s_bio.html
- // implicitly frees internal_bio
- SSL_free(socket->ssl);
- }
+ if (socket->rbio) {
+ //BIO_free(socket->rbio);
+ socket->rbio = tsk_null;
+ }
+ if (socket->wbio) {
+ //BIO_free(socket->wbio);
+ socket->wbio = tsk_null;
+ }
+ if (socket->ssl) {
+ SSL_shutdown(socket->ssl);
+ // https://www.openssl.org/docs/crypto/BIO_s_bio.html
+ // implicitly frees internal_bio
+ SSL_free(socket->ssl);
+ }
#endif
- TSK_FREE(socket->handshake_data.ptr);
- TSK_OBJECT_SAFE_FREE(socket->wrapped_sock);
- tsk_safeobj_deinit(socket);
+ TSK_FREE(socket->handshake_data.ptr);
+ TSK_OBJECT_SAFE_FREE(socket->wrapped_sock);
+ tsk_safeobj_deinit(socket);
- TSK_DEBUG_INFO("*** tnet_dtls_socket_t destroyed ***");
- }
- return self;
+ TSK_DEBUG_INFO("*** tnet_dtls_socket_t destroyed ***");
+ }
+ return self;
}
-static const tsk_object_def_t tnet_dtls_socket_def_s =
-{
- sizeof(tnet_dtls_socket_t),
- tnet_dtls_socket_ctor,
- tnet_dtls_socket_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_dtls_socket_def_s = {
+ sizeof(tnet_dtls_socket_t),
+ tnet_dtls_socket_ctor,
+ tnet_dtls_socket_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_dtls_socket_def_t = &tnet_dtls_socket_def_s;
diff --git a/tinyNET/src/tls/tnet_dtls.h b/tinyNET/src/tls/tnet_dtls.h
index e5b518c..19bb074 100755
--- a/tinyNET/src/tls/tnet_dtls.h
+++ b/tinyNET/src/tls/tnet_dtls.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -34,15 +34,14 @@ struct tnet_socket_s;
typedef void tnet_dtls_socket_handle_t;
-typedef enum tnet_dtls_socket_event_type_e
-{
- tnet_dtls_socket_event_type_handshake_started,
- tnet_dtls_socket_event_type_handshake_succeed,
- tnet_dtls_socket_event_type_handshake_failed,
- tnet_dtls_socket_event_type_fingerprint_mismatch,
- tnet_dtls_socket_event_type_error,
- tnet_dtls_socket_event_type_dtls_srtp_profile_selected, /* SRTP_AES128_CM_SHA1_80 | SRTP_AES128_CM_SHA1_32 */
- tnet_dtls_socket_event_type_dtls_srtp_data, /* key||salt */
+typedef enum tnet_dtls_socket_event_type_e {
+ tnet_dtls_socket_event_type_handshake_started,
+ tnet_dtls_socket_event_type_handshake_succeed,
+ tnet_dtls_socket_event_type_handshake_failed,
+ tnet_dtls_socket_event_type_fingerprint_mismatch,
+ tnet_dtls_socket_event_type_error,
+ tnet_dtls_socket_event_type_dtls_srtp_profile_selected, /* SRTP_AES128_CM_SHA1_80 | SRTP_AES128_CM_SHA1_32 */
+ tnet_dtls_socket_event_type_dtls_srtp_data, /* key||salt */
}
tnet_dtls_socket_event_type_t;
diff --git a/tinyNET/src/tls/tnet_tls.c b/tinyNET/src/tls/tnet_tls.c
index 0ae520c..1904fa3 100755
--- a/tinyNET/src/tls/tnet_tls.c
+++ b/tinyNET/src/tls/tnet_tls.c
@@ -1,19 +1,19 @@
/*
* Copyright (C) 2010-2012 Mamadou Diop.
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -34,270 +34,266 @@
#define TNET_TLS_TIMEOUT 2000
#define TNET_TLS_RETRY_COUNT 10
-typedef struct tnet_tls_socket_s
-{
- TSK_DECLARE_OBJECT;
-
- tnet_fd_t fd; /* not owner: do not try to close */
+typedef struct tnet_tls_socket_s {
+ TSK_DECLARE_OBJECT;
+
+ tnet_fd_t fd; /* not owner: do not try to close */
#if HAVE_OPENSSL
- SSL *ssl;
+ SSL *ssl;
#endif
- TSK_DECLARE_SAFEOBJ;
+ TSK_DECLARE_SAFEOBJ;
}
tnet_tls_socket_t;
tsk_bool_t tnet_tls_is_supported()
{
#if HAVE_OPENSSL
- return tsk_true;
+ return tsk_true;
#else
- return tsk_false;
+ return tsk_false;
#endif
}
tnet_tls_socket_handle_t* tnet_tls_socket_create(tnet_fd_t fd, struct ssl_ctx_st* ssl_ctx)
{
#if !HAVE_OPENSSL
- TSK_DEBUG_ERROR("OpenSSL not enabled");
- return tsk_null;
+ TSK_DEBUG_ERROR("OpenSSL not enabled");
+ return tsk_null;
#else
- tnet_tls_socket_t* socket;
- if(fd <= 0 || !ssl_ctx){
- TSK_DEBUG_ERROR("Invalid parameter");
- return tsk_null;
- }
- if((socket = tsk_object_new(tnet_tls_socket_def_t))){
- socket->fd = fd;
- if(!(socket->ssl = SSL_new(ssl_ctx))){
- TSK_DEBUG_ERROR("SSL_new(CTX) failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- TSK_OBJECT_SAFE_FREE(socket);
- return tsk_null;
- }
- if(SSL_set_fd(socket->ssl, socket->fd) != 1){
- TSK_DEBUG_ERROR("SSL_set_fd(%d) failed [%s]", socket->fd, ERR_error_string(ERR_get_error(), tsk_null));
- TSK_OBJECT_SAFE_FREE(socket);
- return tsk_null;
- }
- }
- return socket;
+ tnet_tls_socket_t* socket;
+ if(fd <= 0 || !ssl_ctx) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return tsk_null;
+ }
+ if((socket = tsk_object_new(tnet_tls_socket_def_t))) {
+ socket->fd = fd;
+ if(!(socket->ssl = SSL_new(ssl_ctx))) {
+ TSK_DEBUG_ERROR("SSL_new(CTX) failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ TSK_OBJECT_SAFE_FREE(socket);
+ return tsk_null;
+ }
+ if(SSL_set_fd(socket->ssl, socket->fd) != 1) {
+ TSK_DEBUG_ERROR("SSL_set_fd(%d) failed [%s]", socket->fd, ERR_error_string(ERR_get_error(), tsk_null));
+ TSK_OBJECT_SAFE_FREE(socket);
+ return tsk_null;
+ }
+ }
+ return socket;
#endif
}
int tnet_tls_socket_connect(tnet_tls_socket_handle_t* self)
{
#if !HAVE_OPENSSL
- TSK_DEBUG_ERROR("You MUST enable OpenSSL");
- return -200;
+ TSK_DEBUG_ERROR("You MUST enable OpenSSL");
+ return -200;
#else
- int ret;
- tnet_tls_socket_t* socket = self;
-
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if((ret = SSL_connect(socket->ssl)) != 1){
- ret = SSL_get_error(socket->ssl, ret);
- if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_SYSCALL){
- ret = 0; /* up to the caller to check that the socket is writable and valid */
- }
- else{
- TSK_DEBUG_ERROR("SSL_connect failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
- }
- }
- else{
- ret = 0;
- }
-
- return ret;
+ int ret;
+ tnet_tls_socket_t* socket = self;
+
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if((ret = SSL_connect(socket->ssl)) != 1) {
+ ret = SSL_get_error(socket->ssl, ret);
+ if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ || ret == SSL_ERROR_SYSCALL) {
+ ret = 0; /* up to the caller to check that the socket is writable and valid */
+ }
+ else {
+ TSK_DEBUG_ERROR("SSL_connect failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
+ }
+ }
+ else {
+ ret = 0;
+ }
+
+ return ret;
#endif
}
int tnet_tls_socket_accept(tnet_tls_socket_handle_t* self)
{
#if !HAVE_OPENSSL
- TSK_DEBUG_ERROR("You MUST enable OpenSSL");
- return -200;
+ TSK_DEBUG_ERROR("You MUST enable OpenSSL");
+ return -200;
#else
- int ret = -1;
- tnet_tls_socket_t* socket = self;
-
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if((ret = SSL_accept(socket->ssl)) != 1){
- ret = SSL_get_error(socket->ssl, ret);
- if(ret == SSL_ERROR_WANT_READ){
- int retval;
- fd_set rfds;
- while (1)
- {
- FD_ZERO(&rfds);
- FD_SET(socket->fd, &rfds);
- retval = select(socket->fd + 1, &rfds, NULL, NULL, NULL);
- if (retval == -1){
- TNET_PRINT_LAST_ERROR("select() failed");
- }
- else if (retval)
- {
- if (FD_ISSET(socket->fd, &rfds)){
- ret = SSL_accept(socket->ssl);
- ret = SSL_get_error(socket->ssl, ret);
- if (ret == SSL_ERROR_WANT_READ){
- continue;
- }
- else{
- if(ret == SSL_ERROR_NONE){
- return 0;
- }
- break;
- }
- }
- }
- else
- {
- break;
- }
- }
- }
- TSK_DEBUG_ERROR("SSL_accept() failed with error code [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
- return -3;
- }
-
- return 0;
+ int ret = -1;
+ tnet_tls_socket_t* socket = self;
+
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if((ret = SSL_accept(socket->ssl)) != 1) {
+ ret = SSL_get_error(socket->ssl, ret);
+ if(ret == SSL_ERROR_WANT_READ) {
+ int retval;
+ fd_set rfds;
+ while (1) {
+ FD_ZERO(&rfds);
+ FD_SET(socket->fd, &rfds);
+ retval = select(socket->fd + 1, &rfds, NULL, NULL, NULL);
+ if (retval == -1) {
+ TNET_PRINT_LAST_ERROR("select() failed");
+ }
+ else if (retval) {
+ if (FD_ISSET(socket->fd, &rfds)) {
+ ret = SSL_accept(socket->ssl);
+ ret = SSL_get_error(socket->ssl, ret);
+ if (ret == SSL_ERROR_WANT_READ) {
+ continue;
+ }
+ else {
+ if(ret == SSL_ERROR_NONE) {
+ return 0;
+ }
+ break;
+ }
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ TSK_DEBUG_ERROR("SSL_accept() failed with error code [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
+ return -3;
+ }
+
+ return 0;
#endif
}
int tnet_tls_socket_write(tnet_tls_socket_handle_t* self, const void* data, tsk_size_t size)
{
#if !HAVE_OPENSSL
- TSK_DEBUG_ERROR("You MUST enable OpenSSL");
- return -200;
+ TSK_DEBUG_ERROR("You MUST enable OpenSSL");
+ return -200;
#else
- int ret = -1;
- tnet_tls_socket_t* socket = self;
- tsk_bool_t try_again = tsk_true, want_read, want_write;
-
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- /* Write */
- tsk_safeobj_lock(socket);
- while(((ret = SSL_write(socket->ssl, data, (int)size)) <= 0) && try_again){
- ret = SSL_get_error(socket->ssl, ret);
- want_read = (ret == SSL_ERROR_WANT_READ);
- want_write = (ret == SSL_ERROR_WANT_WRITE);
-
- if(want_write || want_read){
- if(!(ret = tnet_sockfd_waitUntil(socket->fd, TNET_TLS_TIMEOUT, want_write))){
- continue;
- }
- }
- else{
- TSK_DEBUG_ERROR("SSL_write failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
- ret = -3;
- try_again = tsk_false;
- }
- }
- tsk_safeobj_unlock(socket);
-
- ret = (ret > 0) ? 0 : -3;
- return ret;
+ int ret = -1;
+ tnet_tls_socket_t* socket = self;
+ tsk_bool_t try_again = tsk_true, want_read, want_write;
+
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ /* Write */
+ tsk_safeobj_lock(socket);
+ while(((ret = SSL_write(socket->ssl, data, (int)size)) <= 0) && try_again) {
+ ret = SSL_get_error(socket->ssl, ret);
+ want_read = (ret == SSL_ERROR_WANT_READ);
+ want_write = (ret == SSL_ERROR_WANT_WRITE);
+
+ if(want_write || want_read) {
+ if(!(ret = tnet_sockfd_waitUntil(socket->fd, TNET_TLS_TIMEOUT, want_write))) {
+ continue;
+ }
+ }
+ else {
+ TSK_DEBUG_ERROR("SSL_write failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
+ ret = -3;
+ try_again = tsk_false;
+ }
+ }
+ tsk_safeobj_unlock(socket);
+
+ ret = (ret > 0) ? 0 : -3;
+ return ret;
#endif
}
int tnet_tls_socket_recv(tnet_tls_socket_handle_t* self, void** data, tsk_size_t *size, tsk_bool_t *isEncrypted)
{
#if !HAVE_OPENSSL
- TSK_DEBUG_ERROR("You MUST enable OpenSSL");
- return -200;
+ TSK_DEBUG_ERROR("You MUST enable OpenSSL");
+ return -200;
#else
- int ret = -1;
- tsk_size_t read = 0;
- tsk_size_t to_read = *size;
- int rcount = TNET_TLS_RETRY_COUNT;
- tnet_tls_socket_t* socket = self;
-
- if(!self){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- tsk_safeobj_lock(socket);
-
- *isEncrypted = SSL_is_init_finished(socket->ssl) ? tsk_false : tsk_true;
-
- /* SSL handshake has completed? */
- if(*isEncrypted){
- char* buffer[1024];
- if((ret = SSL_read(socket->ssl, buffer, sizeof(buffer))) <= 0){
- ret = SSL_get_error(socket->ssl, ret);
- if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ){
- ret = 0;
- }
- else{
- TSK_DEBUG_ERROR("SSL_read failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
- }
- *size = 0;
- }
- else{
- *size = ret;
- ret = 0;
- }
-
- goto bail;
- }
-
- /* Read Application data */
-ssl_read:
- if(rcount && ((ret = SSL_read(socket->ssl, (((uint8_t*)*data)+read), (int)to_read)) <= 0)){
- ret = SSL_get_error(socket->ssl, ret);
- if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ){
- if(!(ret = tnet_sockfd_waitUntil(socket->fd, TNET_TLS_TIMEOUT, (ret == SSL_ERROR_WANT_WRITE)))){
- rcount--;
- goto ssl_read;
- }
- }
- else if(SSL_ERROR_ZERO_RETURN){ /* connection closed: do nothing, the transport layer will be alerted. */
- *size = 0;
- ret = 0;
- TSK_DEBUG_INFO("TLS connection closed.");
- }
- else{
- TSK_DEBUG_ERROR("SSL_read failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
- }
- }
- else if(ret >=0){
- read += (tsk_size_t)ret;
-
- if((ret = SSL_pending(socket->ssl)) > 0){
- void *ptr;
- to_read = ret;
-
- if((ptr = tsk_realloc(*data, (read + to_read)))){
- *data = ptr;
- goto ssl_read;
- }
- }
- }
+ int ret = -1;
+ tsk_size_t read = 0;
+ tsk_size_t to_read = *size;
+ int rcount = TNET_TLS_RETRY_COUNT;
+ tnet_tls_socket_t* socket = self;
+
+ if(!self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ tsk_safeobj_lock(socket);
+
+ *isEncrypted = SSL_is_init_finished(socket->ssl) ? tsk_false : tsk_true;
+
+ /* SSL handshake has completed? */
+ if(*isEncrypted) {
+ char* buffer[1024];
+ if((ret = SSL_read(socket->ssl, buffer, sizeof(buffer))) <= 0) {
+ ret = SSL_get_error(socket->ssl, ret);
+ if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ) {
+ ret = 0;
+ }
+ else {
+ TSK_DEBUG_ERROR("SSL_read failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
+ }
+ *size = 0;
+ }
+ else {
+ *size = ret;
+ ret = 0;
+ }
+
+ goto bail;
+ }
+
+ /* Read Application data */
+ssl_read:
+ if(rcount && ((ret = SSL_read(socket->ssl, (((uint8_t*)*data)+read), (int)to_read)) <= 0)) {
+ ret = SSL_get_error(socket->ssl, ret);
+ if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ) {
+ if(!(ret = tnet_sockfd_waitUntil(socket->fd, TNET_TLS_TIMEOUT, (ret == SSL_ERROR_WANT_WRITE)))) {
+ rcount--;
+ goto ssl_read;
+ }
+ }
+ else if(SSL_ERROR_ZERO_RETURN) { /* connection closed: do nothing, the transport layer will be alerted. */
+ *size = 0;
+ ret = 0;
+ TSK_DEBUG_INFO("TLS connection closed.");
+ }
+ else {
+ TSK_DEBUG_ERROR("SSL_read failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
+ }
+ }
+ else if(ret >=0) {
+ read += (tsk_size_t)ret;
+
+ if((ret = SSL_pending(socket->ssl)) > 0) {
+ void *ptr;
+ to_read = ret;
+
+ if((ptr = tsk_realloc(*data, (read + to_read)))) {
+ *data = ptr;
+ goto ssl_read;
+ }
+ }
+ }
bail:
- tsk_safeobj_unlock(socket);
-
- if(read){
- *size = read;
- return 0;
- }
- else{
- return ret;
- }
+ tsk_safeobj_unlock(socket);
+
+ if(read) {
+ *size = read;
+ return 0;
+ }
+ else {
+ return ret;
+ }
#endif
}
@@ -309,34 +305,33 @@ bail:
//
static tsk_object_t* tnet_tls_socket_ctor(tsk_object_t * self, va_list * app)
{
- tnet_tls_socket_t *socket = self;
- if(socket){
- tsk_safeobj_init(socket);
- }
- return self;
+ tnet_tls_socket_t *socket = self;
+ if(socket) {
+ tsk_safeobj_init(socket);
+ }
+ return self;
}
static tsk_object_t* tnet_tls_socket_dtor(tsk_object_t * self)
-{
- tnet_tls_socket_t *socket = self;
- if(socket){
+{
+ tnet_tls_socket_t *socket = self;
+ if(socket) {
#if HAVE_OPENSSL
- if(socket->ssl){
- SSL_shutdown(socket->ssl);
- SSL_free(socket->ssl);
- }
+ if(socket->ssl) {
+ SSL_shutdown(socket->ssl);
+ SSL_free(socket->ssl);
+ }
#endif
- tsk_safeobj_deinit(socket);
- }
- return self;
+ tsk_safeobj_deinit(socket);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_tls_socket_def_s =
-{
- sizeof(tnet_tls_socket_t),
- tnet_tls_socket_ctor,
- tnet_tls_socket_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_tls_socket_def_s = {
+ sizeof(tnet_tls_socket_t),
+ tnet_tls_socket_ctor,
+ tnet_tls_socket_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_tls_socket_def_t = &tnet_tls_socket_def_s;
diff --git a/tinyNET/src/tls/tnet_tls.h b/tinyNET/src/tls/tnet_tls.h
index 5e00ec8..d7bacbc 100755
--- a/tinyNET/src/tls/tnet_tls.h
+++ b/tinyNET/src/tls/tnet_tls.h
@@ -1,19 +1,19 @@
/*
* Copyright (C) 2010-2012 Mamadou Diop.
* Copyright (C) 2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/tnet.c b/tinyNET/src/tnet.c
index 25d763b..0bd15e0 100755
--- a/tinyNET/src/tnet.c
+++ b/tinyNET/src/tnet.c
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2010-2015 Mamadou DIOP.
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -45,7 +45,7 @@
*
* ======
*
-* - @ref tnet_socket_group
+* - @ref tnet_socket_group
* - @ref tnet_utils_group
* - @ref tnet_dhcp_group
* - @ref tnet_dhcp6_group
@@ -70,32 +70,32 @@ tsk_bool_t tnet_isBigEndian = tsk_false;
* You MUST call @ref tnet_cleanup to cleanup the network stack if you no longer need to use networking function.
*
* @sa @ref tnet_cleanup.
- * @return 0 if succeed and error code otherwise.
+ * @return 0 if succeed and error code otherwise.
**/
int tnet_startup()
{
- int err = 0;
- short word = 0x4321;
+ int err = 0;
+ short word = 0x4321;
+
+ if (__tnet_started) {
+ goto bail;
+ }
- if (__tnet_started) {
- goto bail;
- }
-
if ((err = tnet_proxy_node_plugin_register(tnet_proxy_node_socks_plugin_def_t)) != 0) {
goto bail;
}
- // rand()
- srand((unsigned int) tsk_time_epoch());
+ // rand()
+ srand((unsigned int) tsk_time_epoch());
- // endianness
- tnet_isBigEndian = ((*(int8_t *)&word) != 0x21);
+ // endianness
+ tnet_isBigEndian = ((*(int8_t *)&word) != 0x21);
#if TNET_UNDER_WINDOWS
- if (tnet_isBigEndian){
- TSK_DEBUG_ERROR("Big endian on Windows machine. Is it right?");
- }
+ if (tnet_isBigEndian) {
+ TSK_DEBUG_ERROR("Big endian on Windows machine. Is it right?");
+ }
#endif
- // Print messages regardless the debug level
+ // Print messages regardless the debug level
#if TNET_UNDER_WINDOWS_CE && (BUILD_TYPE_GE && SIN_CITY)
# define PRINT_INFO TSK_DEBUG_INFO
# define PRINT_ERROR TSK_DEBUG_ERROR
@@ -105,45 +105,45 @@ int tnet_startup()
#endif
#if TNET_UNDER_WINDOWS
- {
- WORD wVersionRequested;
- WSADATA wsaData;
-
- wVersionRequested = MAKEWORD(2, 2);
-
- err = WSAStartup(wVersionRequested, &wsaData);
- if (err != 0) {
- PRINT_ERROR("WSAStartup failed with error: %d", err);
- return -1;
- }
-
- if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
- PRINT_ERROR("Could not find a usable version of Winsock.dll");
- tnet_cleanup();
- return -2;
- }
- else {
- PRINT_INFO("The Winsock 2.2 dll was found okay");
- }
- }
+ {
+ WORD wVersionRequested;
+ WSADATA wsaData;
+
+ wVersionRequested = MAKEWORD(2, 2);
+
+ err = WSAStartup(wVersionRequested, &wsaData);
+ if (err != 0) {
+ PRINT_ERROR("WSAStartup failed with error: %d", err);
+ return -1;
+ }
+
+ if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
+ PRINT_ERROR("Could not find a usable version of Winsock.dll");
+ tnet_cleanup();
+ return -2;
+ }
+ else {
+ PRINT_INFO("The Winsock 2.2 dll was found okay");
+ }
+ }
#endif /* TNET_UNDER_WINDOWS */
#if HAVE_OPENSSL
- PRINT_INFO("SSL is enabled :)");
- SSL_library_init();
- OpenSSL_add_all_algorithms();
- SSL_load_error_strings();
+ PRINT_INFO("SSL is enabled :)");
+ SSL_library_init();
+ OpenSSL_add_all_algorithms();
+ SSL_load_error_strings();
- PRINT_INFO("DTLS supported: %s", tnet_dtls_is_supported() ? "yes" : "no");
- PRINT_INFO("DTLS-SRTP supported: %s", tnet_dtls_is_srtp_supported() ? "yes" : "no");
+ PRINT_INFO("DTLS supported: %s", tnet_dtls_is_supported() ? "yes" : "no");
+ PRINT_INFO("DTLS-SRTP supported: %s", tnet_dtls_is_srtp_supported() ? "yes" : "no");
#else
- PRINT_ERROR("SSL is disabled :(");
+ PRINT_ERROR("SSL is disabled :(");
#endif
-
- __tnet_started = tsk_true;
+
+ __tnet_started = tsk_true;
bail:
- return err;
+ return err;
}
@@ -155,20 +155,20 @@ bail:
**/
int tnet_cleanup()
{
- if (!__tnet_started){
- goto bail;
- }
-
+ if (!__tnet_started) {
+ goto bail;
+ }
+
tnet_proxy_node_plugin_unregister(tnet_proxy_node_socks_plugin_def_t);
#if TNET_UNDER_WINDOWS
- __tnet_started = tsk_false;
- return WSACleanup();
+ __tnet_started = tsk_false;
+ return WSACleanup();
#else
- __tnet_started = tsk_false;
+ __tnet_started = tsk_false;
#endif
bail:
- return 0;
+ return 0;
}
diff --git a/tinyNET/src/tnet.h b/tinyNET/src/tnet.h
index 92b8e53..94385cc 100755
--- a/tinyNET/src/tnet.h
+++ b/tinyNET/src/tnet.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/tnet_auth.c b/tinyNET/src/tnet_auth.c
index 941db1e..e8cbcfb 100755
--- a/tinyNET/src/tnet_auth.c
+++ b/tinyNET/src/tnet_auth.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/tnet_auth.h b/tinyNET/src/tnet_auth.h
index 1f9642e..36880fd 100755
--- a/tinyNET/src/tnet_auth.h
+++ b/tinyNET/src/tnet_auth.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/tnet_endianness.c b/tinyNET/src/tnet_endianness.c
index 62f1708..f204f0e 100755
--- a/tinyNET/src/tnet_endianness.c
+++ b/tinyNET/src/tnet_endianness.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -39,20 +39,20 @@ extern tsk_bool_t tnet_isBigEndian;
*/
unsigned short tnet_htons(unsigned short x)
{
- if(tnet_is_BE()){
- return x;
- }
- else{
- return ((((uint16_t)(x) & 0xff00) >> 8) |
- (((uint16_t)(x) & 0x00ff) << 8));
- }
+ if(tnet_is_BE()) {
+ return x;
+ }
+ else {
+ return ((((uint16_t)(x) & 0xff00) >> 8) |
+ (((uint16_t)(x) & 0x00ff) << 8));
+ }
}
/* Memory alignment hack */
unsigned short tnet_htons_2(const void* px)
{
- unsigned short y = TSK_TO_UINT16((const uint8_t*)px);
- return tnet_htons(y);
+ unsigned short y = TSK_TO_UINT16((const uint8_t*)px);
+ return tnet_htons(y);
}
/** Converts a 32-bit value from host to TCP/IP network byte order (big-endian).
@@ -61,22 +61,22 @@ unsigned short tnet_htons_2(const void* px)
*/
unsigned long tnet_htonl(unsigned long x)
{
- if(tnet_is_BE()){
- return x;
- }
- else{
- return ((((uint32_t)(x) & 0xff000000) >> 24) | \
- (((uint32_t)(x) & 0x00ff0000) >> 8) | \
- (((uint32_t)(x) & 0x0000ff00) << 8) | \
- (((uint32_t)(x) & 0x000000ff) << 24));
- }
+ if(tnet_is_BE()) {
+ return x;
+ }
+ else {
+ return ((((uint32_t)(x) & 0xff000000) >> 24) | \
+ (((uint32_t)(x) & 0x00ff0000) >> 8) | \
+ (((uint32_t)(x) & 0x0000ff00) << 8) | \
+ (((uint32_t)(x) & 0x000000ff) << 24));
+ }
}
/* Memory alignment hack */
unsigned long tnet_htonl_2(const void* px)
{
- unsigned long y = TSK_TO_UINT32((const uint8_t*)px);
- return tnet_htonl(y);
+ unsigned long y = TSK_TO_UINT32((const uint8_t*)px);
+ return tnet_htonl(y);
}
/** Indicates whether we are on a Big Endian host or not.<br>
@@ -84,15 +84,16 @@ unsigned long tnet_htonl_2(const void* px)
* @ref tnet_startup().
* @retval @a tsk_true if the program is runnin on a Big Endian host and @a tsk_false otherwise.
*/
-tsk_bool_t tnet_is_BE(){
- /* If LITTLE_ENDIAN or BIG_ENDIAN macros have been defined in config.h ==> use them
- * otherwise ==> dyn retrieve the endianness
- */
+tsk_bool_t tnet_is_BE()
+{
+ /* If LITTLE_ENDIAN or BIG_ENDIAN macros have been defined in config.h ==> use them
+ * otherwise ==> dyn retrieve the endianness
+ */
#if LITTLE_ENDIAN
- return tsk_false;
+ return tsk_false;
#elif BIG_ENDIAN
- return tsk_true;
+ return tsk_true;
#else
- return tnet_isBigEndian;
+ return tnet_isBigEndian;
#endif
}
diff --git a/tinyNET/src/tnet_endianness.h b/tinyNET/src/tnet_endianness.h
index 80a1232..4e28e04 100755
--- a/tinyNET/src/tnet_endianness.h
+++ b/tinyNET/src/tnet_endianness.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/tnet_hardwares.h b/tinyNET/src/tnet_hardwares.h
index 7d015b5..641e85d 100755
--- a/tinyNET/src/tnet_hardwares.h
+++ b/tinyNET/src/tnet_hardwares.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,24 +38,23 @@ TNET_BEGIN_DECLS
* List of Hardware types as assigned by the IANA.
* See RFC 1340, 826 and... for more information.
*/
-typedef enum tnet_hardware_type_e
-{
- tnet_htype_Ethernet_10Mb = 1, /**< Ethernet (10Mb) */
- tnet_htype_Ethernet_3Mb = 2, /**< Experimental Ethernet (3Mb) */
- tnet_htype_AX_25 = 3, /**< Amateur Radio AX.25 */
- tnet_htype_Token_Ring = 4, /**< Proteon ProNET Token Ring */
- tnet_htype_Chaos = 5, /**< Chaos */
- tnet_htype_IEEE_802_Networks = 6, /**< IEEE 802 Networks */
- tnet_htype_ARCNET = 7, /**< ARCNET */
- tnet_htype_Hyperchannel = 8, /**< Hyperchannel */
- tnet_htype_Lanstar = 9, /**< Lanstar */
- tnet_htype_Autonet_Short_Address = 10, /**< Autonet Short Address */
- tnet_htype_ALocalTalk = 11, /**< LocalTalk */
- tnet_htype_LocalNet= 12, /**< LocalNet (IBM PCNet or SYTEK LocalNET) */
- tnet_htype_Ultra_link = 13, /**< Ultra link */
- tnet_htype_SMDS = 14, /**< SMDS */
- tnet_htype_Frame_Relay = 15, /**< Frame Relay */
- tnet_htype_ATM = 16, /**< Asynchronous Transmission Mode (ATM) */
+typedef enum tnet_hardware_type_e {
+ tnet_htype_Ethernet_10Mb = 1, /**< Ethernet (10Mb) */
+ tnet_htype_Ethernet_3Mb = 2, /**< Experimental Ethernet (3Mb) */
+ tnet_htype_AX_25 = 3, /**< Amateur Radio AX.25 */
+ tnet_htype_Token_Ring = 4, /**< Proteon ProNET Token Ring */
+ tnet_htype_Chaos = 5, /**< Chaos */
+ tnet_htype_IEEE_802_Networks = 6, /**< IEEE 802 Networks */
+ tnet_htype_ARCNET = 7, /**< ARCNET */
+ tnet_htype_Hyperchannel = 8, /**< Hyperchannel */
+ tnet_htype_Lanstar = 9, /**< Lanstar */
+ tnet_htype_Autonet_Short_Address = 10, /**< Autonet Short Address */
+ tnet_htype_ALocalTalk = 11, /**< LocalTalk */
+ tnet_htype_LocalNet= 12, /**< LocalNet (IBM PCNet or SYTEK LocalNET) */
+ tnet_htype_Ultra_link = 13, /**< Ultra link */
+ tnet_htype_SMDS = 14, /**< SMDS */
+ tnet_htype_Frame_Relay = 15, /**< Frame Relay */
+ tnet_htype_ATM = 16, /**< Asynchronous Transmission Mode (ATM) */
}
tnet_hardware_type_t;
diff --git a/tinyNET/src/tnet_nat.c b/tinyNET/src/tnet_nat.c
index 53a009a..7e536c1 100755
--- a/tinyNET/src/tnet_nat.c
+++ b/tinyNET/src/tnet_nat.c
@@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -40,24 +40,23 @@
/**@defgroup tnet_nat_group NAT Traversal API (STUN, TURN and ICE).
*/
-typedef struct tnet_nat_ctx_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_nat_ctx_s {
+ TSK_DECLARE_OBJECT;
- tnet_socket_type_t socket_type;
+ tnet_socket_type_t socket_type;
- char* username; /**< The username to use to authenticate against the TURN/STUN server. */
- char* password; /**< The password to use to authenticate against the TURN/STUN server. */
+ char* username; /**< The username to use to authenticate against the TURN/STUN server. */
+ char* password; /**< The password to use to authenticate against the TURN/STUN server. */
- char* server_address; /**< TURN/STUN server address (could be FQDN or IP) */
- tnet_port_t server_port; /**< TURN/STUN server port. */
+ char* server_address; /**< TURN/STUN server address (could be FQDN or IP) */
+ tnet_port_t server_port; /**< TURN/STUN server port. */
- uint16_t RTO; /**< Estimate of the round-trip time (RTT) in millisecond. */
- uint16_t Rc; /**< Number of retransmissions for UDP in millisecond. */
+ uint16_t RTO; /**< Estimate of the round-trip time (RTT) in millisecond. */
+ uint16_t Rc; /**< Number of retransmissions for UDP in millisecond. */
- unsigned use_dnsquery:1; /**< Indicates whether to use DNS SRV query to find the stun/turn ip address. */
-
- tnet_stun_bindings_L_t *stun_bindings; /**< List of all STUN2 bindings associated to this context. */
+ unsigned use_dnsquery:1; /**< Indicates whether to use DNS SRV query to find the stun/turn ip address. */
+
+ tnet_stun_bindings_L_t *stun_bindings; /**< List of all STUN2 bindings associated to this context. */
}
tnet_nat_ctx_t;
@@ -67,88 +66,88 @@ tnet_nat_ctx_t;
*/
struct tnet_nat_ctx_s* tnet_nat_context_create(tnet_socket_type_t socket_type, const char* pc_username, const char* pc_password)
{
- extern const tsk_object_def_t *tnet_nat_context_def_t;
- struct tnet_nat_ctx_s* p_ctx;
-
- if (!(p_ctx = tsk_object_new(tnet_nat_context_def_t)) || !(p_ctx->stun_bindings = tsk_list_create())) {
- TSK_OBJECT_SAFE_FREE(p_ctx);
- TSK_DEBUG_ERROR("Failed to create NAT context");
- return tsk_null;
- }
-
- p_ctx->socket_type = socket_type;
- p_ctx->username = tsk_strdup(pc_username);
- p_ctx->password = tsk_strdup(pc_password);
- p_ctx->server_port = kStunPortDefaultTcpUdp;
- /* 7.2.1. Sending over UDP
- In fixed-line access links, a value of 500 ms is RECOMMENDED.
- */
- p_ctx->RTO = kStunRTO;
- /* 7.2.1. Sending over UDP
- Rc SHOULD be configurable and SHOULD have a default of 7.
- */
- p_ctx->Rc = kStunRC;
-
- return p_ctx;
+ extern const tsk_object_def_t *tnet_nat_context_def_t;
+ struct tnet_nat_ctx_s* p_ctx;
+
+ if (!(p_ctx = tsk_object_new(tnet_nat_context_def_t)) || !(p_ctx->stun_bindings = tsk_list_create())) {
+ TSK_OBJECT_SAFE_FREE(p_ctx);
+ TSK_DEBUG_ERROR("Failed to create NAT context");
+ return tsk_null;
+ }
+
+ p_ctx->socket_type = socket_type;
+ p_ctx->username = tsk_strdup(pc_username);
+ p_ctx->password = tsk_strdup(pc_password);
+ p_ctx->server_port = kStunPortDefaultTcpUdp;
+ /* 7.2.1. Sending over UDP
+ In fixed-line access links, a value of 500 ms is RECOMMENDED.
+ */
+ p_ctx->RTO = kStunRTO;
+ /* 7.2.1. Sending over UDP
+ Rc SHOULD be configurable and SHOULD have a default of 7.
+ */
+ p_ctx->Rc = kStunRC;
+
+ return p_ctx;
}
-/** Predicate function to find stun binding by id.
+/** Predicate function to find stun binding by id.
*
- * @param [in,out] item The current list item.
- * @param [in,out] id A pointer to the binding identifier.
+ * @param [in,out] item The current list item.
+ * @param [in,out] id A pointer to the binding identifier.
*
- * @return Zero if current list item hold a binding with the same id and -1 otherwise.
+ * @return Zero if current list item hold a binding with the same id and -1 otherwise.
**/
int __pred_find_stun_binding(const tsk_list_item_t* item, const void* id)
{
- if(item) {
- tnet_stun_binding_t *p_bind = item->data;
- if (p_bind) {
- tnet_stun_binding_id_t binding_id = *((tnet_stun_binding_id_t*)id);
- return (p_bind->id == binding_id) ? 0 : -1;
- }
- }
- return -1;
+ if(item) {
+ tnet_stun_binding_t *p_bind = item->data;
+ if (p_bind) {
+ tnet_stun_binding_id_t binding_id = *((tnet_stun_binding_id_t*)id);
+ return (p_bind->id == binding_id) ? 0 : -1;
+ }
+ }
+ return -1;
}
/**@ingroup tnet_nat_group
*
* Sets the address of the STUN/TURN server.
*
- * @param [in,out] p_self The NAT context.
- * @param [in,out] pc_server_address The address of server.
+ * @param [in,out] p_self The NAT context.
+ * @param [in,out] pc_server_address The address of server.
*
- * @return Zero if succeed and non zero error code otherwise.
+ * @return Zero if succeed and non zero error code otherwise.
**/
int tnet_nat_set_server_address(struct tnet_nat_ctx_s* p_self, const char* pc_server_address)
{
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_strupdate(&(p_self->server_address), pc_server_address);
- return 0;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_strupdate(&(p_self->server_address), pc_server_address);
+ return 0;
}
/**@ingroup tnet_nat_group
*
* Sets the address and port of the STUN/TURN server.
*
- * @param [in,out] p_self The NAT context.
- * @param [in,out] pc_server_address The address of server.
- * @param u_server_port The server port.
+ * @param [in,out] p_self The NAT context.
+ * @param [in,out] pc_server_address The address of server.
+ * @param u_server_port The server port.
*
- * @return Zero if succeed and non zero error code otherwise.
+ * @return Zero if succeed and non zero error code otherwise.
**/
int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_server_address, tnet_port_t u_server_port)
{
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_strupdate(&(p_self->server_address), pc_server_address);
- p_self->server_port = u_server_port;
- return 0;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_strupdate(&(p_self->server_address), pc_server_address);
+ p_self->server_port = u_server_port;
+ return 0;
}
/**@ingroup tnet_nat_group
@@ -156,7 +155,7 @@ int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_server_add
* Creates and sends a STUN2 binding request to the STUN/TURN server in order to get the server reflexive
* address associated to this file descriptor (or socket). The caller should call @ref tnet_nat_stun_unbind to destroy the binding.
*
- * @param [in,out] p_self The NAT context.
+ * @param [in,out] p_self The NAT context.
* @param localFD The local file descriptor (or socket) for which to get the reflexive server address.
*
* @return A valid binding id if succeed and @ref kStunBindingInvalidId otherwise. If the returned id is valid then
@@ -166,13 +165,13 @@ int tnet_nat_set_server(struct tnet_nat_ctx_s* p_self, const char* pc_server_add
**/
tnet_stun_binding_id_t tnet_nat_stun_bind(const struct tnet_nat_ctx_s* p_self, const tnet_fd_t localFD)
{
- tnet_stun_binding_id_t id = kStunBindingInvalidId;
- tnet_stun_binding_t *p_binding = tsk_null;
- int ret;
- if (!p_self || localFD == TNET_INVALID_FD) {
- TSK_DEBUG_ERROR("Invalid parameter");
- goto bail;
- }
+ tnet_stun_binding_id_t id = kStunBindingInvalidId;
+ tnet_stun_binding_t *p_binding = tsk_null;
+ int ret;
+ if (!p_self || localFD == TNET_INVALID_FD) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ goto bail;
+ }
if ((ret = tnet_stun_binding_create(localFD, p_self->socket_type, p_self->server_address, p_self->server_port, p_self->username, p_self->password, &p_binding))) {
goto bail;
}
@@ -183,7 +182,7 @@ tnet_stun_binding_id_t tnet_nat_stun_bind(const struct tnet_nat_ctx_s* p_self, c
tsk_list_push_back_data(p_self->stun_bindings, (void**)&p_binding);
bail:
- TSK_OBJECT_SAFE_FREE(p_binding);
+ TSK_OBJECT_SAFE_FREE(p_binding);
return id;
}
@@ -198,19 +197,19 @@ bail:
**/
int tnet_nat_stun_send_bind(const struct tnet_nat_ctx_s* pc_self, struct tnet_stun_binding_s *p_binding)
{
- int ret = -1;
+ int ret = -1;
tnet_stun_pkt_resp_t *p_pkt_resp = tsk_null;
tnet_stun_pkt_req_t *p_pkt_req = tsk_null;
- if (!pc_self || !p_binding) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!pc_self || !p_binding) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- if (!TNET_SOCKET_TYPE_IS_DGRAM(p_binding->socket_type)) {
- TSK_DEBUG_ERROR("Only DGRAM could be used for STUN transport");
- return -2;
- }
+ if (!TNET_SOCKET_TYPE_IS_DGRAM(p_binding->socket_type)) {
+ TSK_DEBUG_ERROR("Only DGRAM could be used for STUN transport");
+ return -2;
+ }
if ((ret = tnet_stun_binding_create_req(p_binding, &p_pkt_req))) {
goto bail;
@@ -225,51 +224,51 @@ int tnet_nat_stun_send_bind(const struct tnet_nat_ctx_s* pc_self, struct tnet_st
authentication or message integrity applied.
*/
stun_phase0: {
- if ((ret = tnet_stun_utils_send_unreliably(p_binding->localFD, pc_self->RTO, pc_self->Rc, p_pkt_req, (struct sockaddr*)&p_binding->addr_server, &p_pkt_resp))) {
- goto bail;
- }
+ if ((ret = tnet_stun_utils_send_unreliably(p_binding->localFD, pc_self->RTO, pc_self->Rc, p_pkt_req, (struct sockaddr*)&p_binding->addr_server, &p_pkt_resp))) {
+ goto bail;
+ }
if (p_pkt_resp) {
if (TNET_STUN_PKT_RESP_IS_ERROR(p_pkt_resp)) {
- uint16_t u_code;
- if ((ret = tnet_stun_pkt_get_errorcode(p_pkt_resp, &u_code))) {
- goto bail;
- }
- if (u_code == kStunErrCodeUnauthorized || u_code == kStunErrCodeStaleNonce) {
- if (u_code == kStunErrCodeUnauthorized) {
- // Make sure this is not an authentication failure (#2 401)
- // Do not send another req to avoid endless messages
- if ((tnet_stun_pkt_attr_exists(p_pkt_req, tnet_stun_attr_type_message_integrity))) { // already has a MESSAGE-INTEGRITY?
- TSK_DEBUG_ERROR("STUN authentication failed");
- goto bail;
- }
- }
- if ((ret = tnet_stun_pkt_auth_prepare_2(p_pkt_req, p_binding->p_username, p_binding->p_password, p_pkt_resp))) {
- goto bail;
- }
- // Try to send again now that authinfo is up2date
- goto stun_phase0;
- }
- else if (u_code == kStunErrCodeUnknownAttributes) {
- if((ret = tnet_stun_pkt_process_err420(p_pkt_req, p_pkt_resp))) {
- goto bail;
- }
- // Try to send again now that authinfo is up2date
- goto stun_phase0;
- }
- ret = -3;
+ uint16_t u_code;
+ if ((ret = tnet_stun_pkt_get_errorcode(p_pkt_resp, &u_code))) {
+ goto bail;
+ }
+ if (u_code == kStunErrCodeUnauthorized || u_code == kStunErrCodeStaleNonce) {
+ if (u_code == kStunErrCodeUnauthorized) {
+ // Make sure this is not an authentication failure (#2 401)
+ // Do not send another req to avoid endless messages
+ if ((tnet_stun_pkt_attr_exists(p_pkt_req, tnet_stun_attr_type_message_integrity))) { // already has a MESSAGE-INTEGRITY?
+ TSK_DEBUG_ERROR("STUN authentication failed");
+ goto bail;
+ }
+ }
+ if ((ret = tnet_stun_pkt_auth_prepare_2(p_pkt_req, p_binding->p_username, p_binding->p_password, p_pkt_resp))) {
+ goto bail;
+ }
+ // Try to send again now that authinfo is up2date
+ goto stun_phase0;
+ }
+ else if (u_code == kStunErrCodeUnknownAttributes) {
+ if((ret = tnet_stun_pkt_process_err420(p_pkt_req, p_pkt_resp))) {
+ goto bail;
+ }
+ // Try to send again now that authinfo is up2date
+ goto stun_phase0;
+ }
+ ret = -3;
}
else {
- const tnet_stun_attr_address_t* pc_addr;
- if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) {
- TSK_OBJECT_SAFE_FREE(p_binding->p_xmaddr);
- p_binding->p_xmaddr = tsk_object_ref(TSK_OBJECT(pc_addr));
- }
- if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) {
- TSK_OBJECT_SAFE_FREE(p_binding->p_maddr);
- p_binding->p_maddr = tsk_object_ref(TSK_OBJECT(pc_addr));
- }
- }
+ const tnet_stun_attr_address_t* pc_addr;
+ if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) {
+ TSK_OBJECT_SAFE_FREE(p_binding->p_xmaddr);
+ p_binding->p_xmaddr = tsk_object_ref(TSK_OBJECT(pc_addr));
+ }
+ if ((ret = tnet_stun_pkt_attr_find_first(p_pkt_resp, tnet_stun_attr_type_mapped_address, (const tnet_stun_attr_t**)&pc_addr)) == 0 && pc_addr) {
+ TSK_OBJECT_SAFE_FREE(p_binding->p_maddr);
+ p_binding->p_maddr = tsk_object_ref(TSK_OBJECT(pc_addr));
+ }
+ }
}
}
/* END OF stun_phase0 */
@@ -285,51 +284,51 @@ bail:
* Gets the server reflexive address associated to this STUN2 binding.
*
*
- * @param [in,out] p_self The NAT context.
- * @param id The id of the STUN2 binding conetxt (obtained using @ref tnet_nat_stun_bind) holding the server-reflexive address.
- * @param [in,out] pp_ip The reflexive IP address. It is up the the caller to free the returned string
- * @param [in,out] pu_port The reflexive port.
+ * @param [in,out] p_self The NAT context.
+ * @param id The id of the STUN2 binding conetxt (obtained using @ref tnet_nat_stun_bind) holding the server-reflexive address.
+ * @param [in,out] pp_ip The reflexive IP address. It is up the the caller to free the returned string
+ * @param [in,out] pu_port The reflexive port.
*
- * @return Zero if succeed and non zero error code otherwise.
+ * @return Zero if succeed and non zero error code otherwise.
**/
int tnet_nat_stun_get_reflexive_address(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_id_t id, char** pp_ip, tnet_port_t *pu_port)
{
- const tsk_list_item_t* item;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (!pp_ip && !pu_port) {
- return 0;
- }
-
- if ((item = tsk_list_find_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id)) && item->data) {
- const tnet_stun_binding_t *pc_bind = (const tnet_stun_binding_t *)item->data;
- const struct tnet_stun_attr_address_s *pc_addr = pc_bind->p_xmaddr ? pc_bind->p_xmaddr : pc_bind->p_maddr;
- if (pc_addr) {
- tnet_ip_t ip;
- int ret;
- if ((ret = tnet_stun_utils_inet_ntop((pc_addr->e_family == tnet_stun_address_family_ipv6), &pc_addr->address, &ip))) {
- return ret;
- }
- if (pp_ip) {
- tsk_strupdate(pp_ip, ip);
- }
- if (pu_port) {
- *pu_port = pc_addr->u_port;
- }
- return 0;
- }
- }
- return -2;
+ const tsk_list_item_t* item;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (!pp_ip && !pu_port) {
+ return 0;
+ }
+
+ if ((item = tsk_list_find_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id)) && item->data) {
+ const tnet_stun_binding_t *pc_bind = (const tnet_stun_binding_t *)item->data;
+ const struct tnet_stun_attr_address_s *pc_addr = pc_bind->p_xmaddr ? pc_bind->p_xmaddr : pc_bind->p_maddr;
+ if (pc_addr) {
+ tnet_ip_t ip;
+ int ret;
+ if ((ret = tnet_stun_utils_inet_ntop((pc_addr->e_family == tnet_stun_address_family_ipv6), &pc_addr->address, &ip))) {
+ return ret;
+ }
+ if (pp_ip) {
+ tsk_strupdate(pp_ip, ip);
+ }
+ if (pu_port) {
+ *pu_port = pc_addr->u_port;
+ }
+ return 0;
+ }
+ }
+ return -2;
}
/**@ingroup tnet_nat_group
*
* Removes a STUN2 binding from the NAT context.
*
- * @param [in,out] p_self The NAT context from which to remove the STUN2 binding.
- * @param id The id of the STUN2 binding to remove.
+ * @param [in,out] p_self The NAT context from which to remove the STUN2 binding.
+ * @param id The id of the STUN2 binding to remove.
*
* @return Zero if succeed and non zero error code otherwise.
*
@@ -338,12 +337,12 @@ int tnet_nat_stun_get_reflexive_address(const struct tnet_nat_ctx_s* p_self, tne
**/
int tnet_nat_stun_unbind(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_id_t id)
{
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_list_remove_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id);
- return 0;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_list_remove_item_by_pred(p_self->stun_bindings, __pred_find_stun_binding, &id);
+ return 0;
}
@@ -352,30 +351,29 @@ int tnet_nat_stun_unbind(const struct tnet_nat_ctx_s* p_self, tnet_stun_binding_
//
static tsk_object_t* tnet_nat_context_ctor(tsk_object_t * self, va_list * app)
{
- tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self;
- if (p_ctx) {
- }
- return self;
+ tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self;
+ if (p_ctx) {
+ }
+ return self;
}
static tsk_object_t* tnet_nat_context_dtor(tsk_object_t * self)
-{
- tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self;
- if (p_ctx) {
- TSK_FREE(p_ctx->username);
- TSK_FREE(p_ctx->password);
- TSK_FREE(p_ctx->server_address);
-
- TSK_OBJECT_SAFE_FREE(p_ctx->stun_bindings);
- TSK_DEBUG_INFO("*** NAT context destroyed ***");
- }
-
- return self;
-}
-static const tsk_object_def_t tnet_nat_context_def_s =
{
- sizeof(tnet_nat_ctx_t),
- tnet_nat_context_ctor,
- tnet_nat_context_dtor,
- tsk_null,
+ tnet_nat_ctx_t *p_ctx = (tnet_nat_ctx_t*)self;
+ if (p_ctx) {
+ TSK_FREE(p_ctx->username);
+ TSK_FREE(p_ctx->password);
+ TSK_FREE(p_ctx->server_address);
+
+ TSK_OBJECT_SAFE_FREE(p_ctx->stun_bindings);
+ TSK_DEBUG_INFO("*** NAT context destroyed ***");
+ }
+
+ return self;
+}
+static const tsk_object_def_t tnet_nat_context_def_s = {
+ sizeof(tnet_nat_ctx_t),
+ tnet_nat_context_ctor,
+ tnet_nat_context_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_nat_context_def_t = &tnet_nat_context_def_s;
diff --git a/tinyNET/src/tnet_nat.h b/tinyNET/src/tnet_nat.h
index 46d774f..626851d 100755
--- a/tinyNET/src/tnet_nat.h
+++ b/tinyNET/src/tnet_nat.h
@@ -6,12 +6,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
diff --git a/tinyNET/src/tnet_poll.c b/tinyNET/src/tnet_poll.c
index 816f9c6..ebde819 100755
--- a/tinyNET/src/tnet_poll.c
+++ b/tinyNET/src/tnet_poll.c
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -25,11 +25,11 @@
/**
*
- * @brief poll() method implementation for multiplexing network sockets.
+ * @brief poll() method implementation for multiplexing network sockets.
*
- * @param fds An array of pollfd structures.
- * @param nfds The number of file descriptors set in fds[ ].
- * @param timeout How long poll() should wait for an event to occur (in milliseconds).
+ * @param fds An array of pollfd structures.
+ * @param nfds The number of file descriptors set in fds[ ].
+ * @param timeout How long poll() should wait for an event to occur (in milliseconds).
*
* @return The number of elements in fdarray for which an revents member of the POLLFD structure is nonzero.
* If the the returned value if <0 this mean that error occurred.
@@ -37,71 +37,71 @@
int tnet_poll(tnet_pollfd_t fds[ ], tnet_nfds_t nfds, int timeout)
{
- tsk_size_t i;
- int ret;
- int highest_fd = -1;
+ tsk_size_t i;
+ int ret;
+ int highest_fd = -1;
+
+ fd_set readfds;
+ fd_set writefds;
+ fd_set exceptfds;
+ struct timeval timetowait;
+
+ /*
+ * cleanup fd_sets
+ */
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
- fd_set readfds;
- fd_set writefds;
- fd_set exceptfds;
- struct timeval timetowait;
+ /*
+ * set timeout
+ */
+ if(timeout >=0) {
+ timetowait.tv_sec = (timeout/1000);
+ timetowait.tv_usec = (timeout%1000) * 1000;
+ }
- /*
- * cleanup fd_sets
- */
- FD_ZERO(&readfds);
- FD_ZERO(&writefds);
- FD_ZERO(&exceptfds);
+ /*
+ * add descriptors to the fd_sets
+ */
+ for(i = 0; i<nfds; i++) {
+ if(fds[i].fd != TNET_INVALID_FD) {
+ if(fds[i].events & TNET_POLLIN) {
+ FD_SET(fds[i].fd, &readfds);
+ }
+ if(fds[i].events & TNET_POLLOUT) {
+ FD_SET(fds[i].fd, &writefds);
+ }
+ if(fds[i].events & TNET_POLLPRI) {
+ FD_SET(fds[i].fd, &exceptfds);
+ }
+ }
- /*
- * set timeout
- */
- if(timeout >=0){
- timetowait.tv_sec = (timeout/1000);
- timetowait.tv_usec = (timeout%1000) * 1000;
- }
+ highest_fd = (highest_fd < fds[i].fd) ? fds[i].fd : highest_fd;
+ }
- /*
- * add descriptors to the fd_sets
- */
- for(i = 0; i<nfds; i++){
- if(fds[i].fd != TNET_INVALID_FD){
- if(fds[i].events & TNET_POLLIN){
- FD_SET(fds[i].fd, &readfds);
- }
- if(fds[i].events & TNET_POLLOUT){
- FD_SET(fds[i].fd, &writefds);
- }
- if(fds[i].events & TNET_POLLPRI){
- FD_SET(fds[i].fd, &exceptfds);
- }
- }
-
- highest_fd = (highest_fd < fds[i].fd) ? fds[i].fd : highest_fd;
- }
-
- /*======================================
- * select
- */
- if((ret = select(highest_fd + 1, &readfds, &writefds, &exceptfds, (timeout >=0) ? &timetowait : 0)) >= 0){
- for(i = 0; i<nfds; i++){
- if(fds[i].fd != TNET_INVALID_FD){
- fds[i].revents = 0;
+ /*======================================
+ * select
+ */
+ if((ret = select(highest_fd + 1, &readfds, &writefds, &exceptfds, (timeout >=0) ? &timetowait : 0)) >= 0) {
+ for(i = 0; i<nfds; i++) {
+ if(fds[i].fd != TNET_INVALID_FD) {
+ fds[i].revents = 0;
- if(FD_ISSET(fds[i].fd, &readfds)){
- fds[i].revents |= TNET_POLLIN;
- }
- if(FD_ISSET(fds[i].fd, &writefds)){
- fds[i].revents |= TNET_POLLOUT;
- }
- if(FD_ISSET(fds[i].fd, &exceptfds)){
- fds[i].revents |= TNET_POLLPRI;
- }
- }
- }
- }
+ if(FD_ISSET(fds[i].fd, &readfds)) {
+ fds[i].revents |= TNET_POLLIN;
+ }
+ if(FD_ISSET(fds[i].fd, &writefds)) {
+ fds[i].revents |= TNET_POLLOUT;
+ }
+ if(FD_ISSET(fds[i].fd, &exceptfds)) {
+ fds[i].revents |= TNET_POLLPRI;
+ }
+ }
+ }
+ }
- return ret;
+ return ret;
}
#endif /* TNET_USE_POLL */
diff --git a/tinyNET/src/tnet_poll.h b/tinyNET/src/tnet_poll.h
index becd1c3..a9c4a0f 100755
--- a/tinyNET/src/tnet_poll.h
+++ b/tinyNET/src/tnet_poll.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -44,7 +44,7 @@ typedef unsigned long tnet_nfds_t;
typedef struct pollfd tnet_pollfd_t;
-#define TNET_POLLRDNORM POLLRDNORM
+#define TNET_POLLRDNORM POLLRDNORM
#define TNET_POLLRDBAND POLLRDBAND
#define TNET_POLLIN POLLIN
#define TNET_POLLPRI POLLPRI
@@ -65,8 +65,7 @@ typedef struct pollfd tnet_pollfd_t;
#else
-typedef struct tnet_pollfd_s
-{
+typedef struct tnet_pollfd_s {
tnet_fd_t fd;
short events;
short revents;
diff --git a/tinyNET/src/tnet_proto.h b/tinyNET/src/tnet_proto.h
index ef7d89e..3365989 100755
--- a/tinyNET/src/tnet_proto.h
+++ b/tinyNET/src/tnet_proto.h
@@ -2,19 +2,19 @@
* Copyright (C) 2010-2011 Mamadou Diop.
*
* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -37,156 +37,155 @@ TNET_BEGIN_DECLS
/**
* @enum tnet_proto_e
*
- * @brief List of all assigned protocols as defined by the IANA
+ * @brief List of all assigned protocols as defined by the IANA
(http://www.iana.org/assignments/protocol-numbers/).
**/
-typedef enum tnet_proto_e
-{
- TNET_PROTO_HOPOPT = 0, /**< HOPOPT IPv6 Hop-by-Hop Option [RFC1883] */
- TNET_PROTO_ICMP = 1, /**< ICMP Internet Control Message [RFC792] */
- TNET_PROTO_IGMP = 2, /**< IGMP Internet Group Management [RFC1112] */
- TNET_PROTO_GGP = 3, /**< GGP Gateway-to-Gateway [RFC823] */
- TNET_PROTO_IP = 4, /**< IP IP in IP (encapsulation) [RFC2003] */
- TNET_PROTO_ST = 5, /**< ST Stream [RFC1190][RFC1819] */
- TNET_PROTO_TCP = 6, /**< TCP Transmission Control [RFC793] */
- TNET_PROTO_CBT = 7, /**< CBT CBT [Ballardie] */
- TNET_PROTO_EGP = 8, /**< EGP Exterior Gateway Protocol [RFC888][DLM1] */
- TNET_PROTO_IGP = 9, /**< IGP any private interior gateway [IANA](used by Cisco for their IGRP) */
- TNET_PROTO_BBN_RCC_MON = 10, /**< BBN-RCC-MON BBN RCC Monitoring [SGC] */
- TNET_PROTO_NVP_II = 11, /**< NVP-II Network Voice Protocol [RFC741][SC3] */
- TNET_PROTO_PUP = 12, /**< PUP PUP [PUP][XEROX] */
- TNET_PROTO_ARGUS = 13, /**< ARGUS ARGUS [RWS4] */
- TNET_PROTO_EMCON = 14, /**< EMCON EMCON [BN7] */
- TNET_PROTO_XNET = 15, /**< XNET Cross Net Debugger [IEN158][JFH2] */
- TNET_PROTO_CHAOS = 16, /**< CHAOS Chaos [NC3] */
- TNET_PROTO_UDP = 17, /**< UDP User Datagram [RFC768][JBP] */
- TNET_PROTO_MUX = 18, /**< MUX Multiplexing [IEN90][JBP] */
- TNET_PROTO_DCN_MEAS = 19, /**< DCN-MEAS DCN Measurement Subsystems [DLM1] */
- TNET_PROTO_HMP = 20, /**< HMP Host Monitoring [RFC869][RH6] */
- TNET_PROTO_PRM = 21, /**< PRM Packet Radio Measurement [ZSU] */
- TNET_PROTO_XNS_IDP = 22, /**< XNS-IDP XEROX NS IDP [ETHERNET][XEROX] */
- TNET_PROTO_TRUNK_1 = 23, /**< TRUNK-1 Trunk-1 [BWB6] */
- TNET_PROTO_TRUNK_2 = 24, /**< TRUNK-2 Trunk-2 [BWB6] */
- TNET_PROTO_LEAF_1 = 25, /**< LEAF-1 Leaf-1 [BWB6] */
- TNET_PROTO_LEAF_2 = 26, /**< LEAF-2 Leaf-2 [BWB6] */
- TNET_PROTO_RDP = 27, /**< RDP Reliable Data Protocol [RFC908][RH6] */
- TNET_PROTO_IRTP = 28, /**< IRTP Internet Reliable Transaction [RFC938][TXM] */
- TNET_PROTO_ISO_TP4 = 29, /**< ISO-TP4 ISO Transport Protocol Class 4 [RFC905][RC77] */
- TNET_PROTO_NETBLT = 30, /**< NETBLT Bulk Data Transfer Protocol [RFC969][DDC1] */
- TNET_PROTO_MFE_NSP = 31, /**< MFE-NSP MFE Network Services Protocol [MFENET][BCH2] */
- TNET_PROTO_MERIT_INP = 32, /**< MERIT-INP MERIT Internodal Protocol [HWB] */
- TNET_PROTO_DCCP = 33, /**< DCCP Datagram Congestion Control Protocol [RFC4340] */
- TNET_PROTO_3PC = 34, /**< 3PC Third Party Connect Protocol [SAF3] */
- TNET_PROTO_IDPR = 35, /**< IDPR Inter-Domain Policy Routing Protocol [MXS1] */
- TNET_PROTO_XTP = 36, /**< XTP XTP [GXC] */
- TNET_PROTO_DDP = 37, /**< DDP Datagram Delivery Protocol [WXC] */
- TNET_PROTO_IDPR_CMTP = 38, /**< IDPR-CMTP IDPR Control Message Transport Proto [MXS1] */
- TNET_PROTO_TP_PP = 39, /**< TP++ TP++ Transport Protocol [DXF] */
- TNET_PROTO_IL = 40, /**< IL IL Transport Protocol [Presotto] */
- TNET_PROTO_IPv6 = 41, /**< IPv6 Ipv6 [Deering] */
- TNET_PROTO_SDRP = 42, /**< SDRP Source Demand Routing Protocol [DXE1] */
- TNET_PROTO_IPv6_Route = 43, /**< IPv6-Route Routing Header for IPv6 [Deering] */
- TNET_PROTO_IPv6_Frag = 44, /**< IPv6-Frag Fragment Header for IPv6 [Deering] */
- TNET_PROTO_IDRP = 45, /**< IDRP Inter-Domain Routing Protocol [Hares] */
- TNET_PROTO_RSVP = 46, /**< RSVP Reservation Protocol [Braden] */
- TNET_PROTO_GRE = 47, /**< GRE General Routing Encapsulation [Li] */
- TNET_PROTO_DSR = 48, /**< DSR Dynamic Source Routing Protocol [RFC4728] */
- TNET_PROTO_BNA = 49, /**< BNA BNA [Salamon] */
- TNET_PROTO_ESP = 50, /**< ESP Encap Security Payload [RFC4303] */
- TNET_PROTO_AH = 51, /**< AH Authentication Header [RFC4302] */
- TNET_PROTO_I_NLSP = 52, /**< I-NLSP Integrated Net Layer Security TUBA [GLENN] */
- TNET_PROTO_SWIPE = 53, /**< SWIPE IP with Encryption [JI6] */
- TNET_PROTO_NARP = 54, /**< NARP NBMA Address Resolution Protocol [RFC1735] */
- TNET_PROTO_MOBILE = 55, /**< MOBILE IP Mobility [Perkins] */
- TNET_PROTO_TLSP = 56, /**< TLSP Transport Layer Security Protocol [Oberg] using Kryptonet key management */
- TNET_PROTO_SKIP = 57, /**< SKIP SKIP [Markson] */
- TNET_PROTO_IPv6_ICMP = 58, /**< IPv6-ICMP ICMP for IPv6 [RFC1883] */
- TNET_PROTO_IPv6_NoNxt = 59, /**< IPv6-NoNxt No Next Header for IPv6 [RFC1883] */
- TNET_PROTO_IPv6_Opts = 60, /**< IPv6-Opts Destination Options for IPv6 [RFC1883] */
- TNET_PROTO_ANY_INTERNAL = 61, /**< any host internal protocol [IANA] */
- TNET_PROTO_CFTP = 62, /**< CFTP CFTP [CFTP][HCF2] */
- TNET_PROTO_ANY_LOCAL = 63, /**< any local network [IANA] */
- TNET_PROTO_SAT_EXPAK = 64, /**< SAT-EXPAK SATNET and Backroom EXPAK [SHB] */
- TNET_PROTO_KRYPTOLAN = 65, /**< KRYPTOLAN Kryptolan [PXL1] */
- TNET_PROTO_RVD = 66, /**< RVD MIT Remote Virtual Disk Protocol [MBG] */
- TNET_PROTO_IPPC = 67, /**< IPPC Internet Pluribus Packet Core [SHB] */
- TNET_PROTO_ANY_DISTRIBUTED = 68, /**< any distributed file system [IANA] */
- TNET_PROTO_SAT_MON = 69, /**< SAT-MON SATNET Monitoring [SHB] */
- TNET_PROTO_VISA = 70, /**< VISA VISA Protocol [GXT1] */
- TNET_PROTO_IPCV = 71, /**< IPCV Internet Packet Core Utility [SHB] */
- TNET_PROTO_CPNX = 72, /**< CPNX Computer Protocol Network Executive [DXM2] */
- TNET_PROTO_CPHB = 73, /**< CPHB Computer Protocol Heart Beat [DXM2] */
- TNET_PROTO_WSN = 74, /**< WSN Wang Span Network [VXD] */
- TNET_PROTO_PVP = 75, /**< PVP Packet Video Protocol [SC3] */
- TNET_PROTO_BR_SAT_MON = 76, /**< BR-SAT-MON Backroom SATNET Monitoring [SHB] */
- TNET_PROTO_SUN_ND = 77, /**< SUN-ND SUN ND PROTOCOL-Temporary [WM3] */
- TNET_PROTO_WB_MON = 78, /**< WB-MON WIDEBAND Monitoring [SHB] */
- TNET_PROTO_WB_EXPAK = 79, /**< WB-EXPAK WIDEBAND EXPAK [SHB] */
- TNET_PROTO_ISO_IP = 80, /**< ISO-IP ISO Internet Protocol [MTR] */
- TNET_PROTO_VMTP = 81, /**< VMTP VMTP [DRC3] */
- TNET_PROTO_SECURE_VMTP = 82, /**< SECURE-VMTP SECURE-VMTP [DRC3] */
- TNET_PROTO_VINES = 83, /**< VINES VINES [BXH] */
- TNET_PROTO_TTP = 84, /**< TTP TTP [JXS] */
- TNET_PROTO_NSFNET_IGP = 85, /**< NSFNET-IGP NSFNET-IGP [HWB] */
- TNET_PROTO_DGP = 86, /**< DGP Dissimilar Gateway Protocol [DGP][ML109] */
- TNET_PROTO_TCF = 87, /**< TCF TCF [GAL5] */
- TNET_PROTO_EIGRP = 88, /**< EIGRP EIGRP [CISCO][GXS] */
- TNET_PROTO_OSPFIGP = 89, /**< OSPFIGP OSPFIGP [RFC1583][JTM4] */
- TNET_PROTO_Sprite_RPC = 90, /**< Sprite-RPC Sprite RPC Protocol [SPRITE][BXW] */
- TNET_PROTO_LARP = 91, /**< LARP Locus Address Resolution Protocol [BXH] */
- TNET_PROTO_MTP = 92, /**< MTP Multicast Transport Protocol [SXA] */
- TNET_PROTO_AX25 = 93, /**< AX.25 AX.25 Frames [BK29] */
- TNET_PROTO_IPIP = 94, /**< IPIP IP-within-IP Encapsulation Protocol [JI6] */
- TNET_PROTO_MICP = 95, /**< MICP Mobile Internetworking Control Pro. [JI6] */
- TNET_PROTO_SCC_SP = 96, /**< SCC-SP Semaphore Communications Sec. Pro. [HXH] */
- TNET_PROTO_ETHERIP = 97, /**< ETHERIP Ethernet-within-IP Encapsulation [RFC3378] */
- TNET_PROTO_ENCAP = 98, /**< ENCAP Encapsulation Header [RFC1241,RXB3] */
- TNET_PROTO_ANY_PRIV_ENC = 99, /**< any private encryption scheme [IANA] */
- TNET_PROTO_GMTP = 100, /**< GMTP GMTP [RXB5] */
- TNET_PROTO_IFMP = 101, /**< IFMP Ipsilon Flow Management Protocol [Hinden] */
- TNET_PROTO_PNNI = 102, /**< PNNI PNNI over IP [Callon] */
- TNET_PROTO_PIM = 103, /**< PIM Protocol Independent Multicast [Farinacci] */
- TNET_PROTO_ARIS = 104, /**< ARIS ARIS [Feldman] */
- TNET_PROTO_SCPS = 105, /**< SCPS SCPS [Durst] */
- TNET_PROTO_QNX = 106, /**< QNX QNX [Hunter] */
- TNET_PROTO_AN = 107, /**< A/N Active Networks [Braden] */
- TNET_PROTO_IPComp = 108, /**< IPComp IP Payload Compression Protocol [RFC2393] */
- TNET_PROTO_SNP = 109, /**< SNP Sitara Networks Protocol [Sridhar] */
- TNET_PROTO_Compaq_Peer = 110, /**< Compaq-Peer Compaq Peer Protocol [Volpe] */
- TNET_PROTO_IPX_in_IP = 11, /**< IPX-in-IP IPX in IP [Lee] */
- TNET_PROTO_VRRP = 112, /**< VRRP Virtual Router Redundancy Protocol [RFC3768][RFC-ietf-vrrp-unified-spec-05.txt] */
- TNET_PROTO_PGM = 113, /**< PGM PGM Reliable Transport Protocol [Speakman] */
- TNET_PROTO_ANY_ZERO_HOP = 114, /**< any 0-hop protocol [IANA] */
- TNET_PROTO_L2TP = 115, /**< L2TP Layer Two Tunneling Protocol [Aboba] */
- TNET_PROTO_DDX = 116, /**< DDX D-II Data Exchange (DDX) [Worley] */
- TNET_PROTO_IATP = 117, /**< IATP Interactive Agent Transfer Protocol [Murphy] */
- TNET_PROTO_STP = 118, /**< STP Schedule Transfer Protocol [JMP] */
- TNET_PROTO_SRP = 119, /**< SRP SpectraLink Radio Protocol [Hamilton] */
- TNET_PROTO_UTI = 120, /**< UTI UTI [Lothberg] */
- TNET_PROTO_SMP = 121, /**< SMP Simple Message Protocol [Ekblad] */
- TNET_PROTO_SM = 122, /**< SM SM [Crowcroft] */
- TNET_PROTO_PTP = 123, /**< PTP Performance Transparency Protocol [Welzl] */
- TNET_PROTO_ISIS = 124, /**< ISIS over IPv4 [Przygienda] */
- TNET_PROTO_FIRE = 125, /**< FIRE [Partridge] */
- TNET_PROTO_CRTP = 126, /**< CRTP Combat Radio Transport Protocol [Sautter] */
- TNET_PROTO_CRUDP = 127, /**< CRUDP Combat Radio User Datagram [Sautter] */
- TNET_PROTO_SSCOPMCE = 128, /**< SSCOPMCE [Waber] */
- TNET_PROTO_IPLT = 129, /**< IPLT [Hollbach] */
- TNET_PROTO_SPS = 130, /**< SPS Secure Packet Shield [McIntosh] */
- TNET_PROTO_PIPE = 131, /**< PIPE Private IP Encapsulation within IP [Petri] */
- TNET_PROTO_SCTP = 132, /**< SCTP Stream Control Transmission Protocol [Stewart] */
- TNET_PROTO_FC = 133, /**< FC Fibre Channel [Rajagopal] */
- TNET_PROTO_RSVP_E2E_IGNORE = 134, /**< RSVP-E2E-IGNORE [RFC3175] */
- TNET_PROTO_Mobility_Header = 135, /**< Mobility Header [RFC3775] */
- TNET_PROTO_UDPLite = 136, /**< UDPLite [RFC3828] */
- TNET_PROTO_MPLS_in_IP = 137, /**< MPLS-in-IP [RFC4023] */
- TNET_PROTO_manet = 138, /**< manet MANET Protocols [RFC5498] */
- TNET_PROTO_HIP = 139, /**< HIP Host Identity Protocol [RFC5201] */
- TNET_PROTO_Shim6 = 140, /**< Shim6 Shim6 Protocol [RFC5533] */
- //TNET_PROTO_ = 141-252 Unassigned [IANA]
- TNET_PROTO_EXP1 = 253, /**< Use for experimentation and testing [RFC3692] */
- TNET_PROTO_EXP2 = 254, /**< Use for experimentation and testing [RFC3692] */
- TNET_PROTO_Reserved = 255, /**< Reserved [IANA] */
+typedef enum tnet_proto_e {
+ TNET_PROTO_HOPOPT = 0, /**< HOPOPT IPv6 Hop-by-Hop Option [RFC1883] */
+ TNET_PROTO_ICMP = 1, /**< ICMP Internet Control Message [RFC792] */
+ TNET_PROTO_IGMP = 2, /**< IGMP Internet Group Management [RFC1112] */
+ TNET_PROTO_GGP = 3, /**< GGP Gateway-to-Gateway [RFC823] */
+ TNET_PROTO_IP = 4, /**< IP IP in IP (encapsulation) [RFC2003] */
+ TNET_PROTO_ST = 5, /**< ST Stream [RFC1190][RFC1819] */
+ TNET_PROTO_TCP = 6, /**< TCP Transmission Control [RFC793] */
+ TNET_PROTO_CBT = 7, /**< CBT CBT [Ballardie] */
+ TNET_PROTO_EGP = 8, /**< EGP Exterior Gateway Protocol [RFC888][DLM1] */
+ TNET_PROTO_IGP = 9, /**< IGP any private interior gateway [IANA](used by Cisco for their IGRP) */
+ TNET_PROTO_BBN_RCC_MON = 10, /**< BBN-RCC-MON BBN RCC Monitoring [SGC] */
+ TNET_PROTO_NVP_II = 11, /**< NVP-II Network Voice Protocol [RFC741][SC3] */
+ TNET_PROTO_PUP = 12, /**< PUP PUP [PUP][XEROX] */
+ TNET_PROTO_ARGUS = 13, /**< ARGUS ARGUS [RWS4] */
+ TNET_PROTO_EMCON = 14, /**< EMCON EMCON [BN7] */
+ TNET_PROTO_XNET = 15, /**< XNET Cross Net Debugger [IEN158][JFH2] */
+ TNET_PROTO_CHAOS = 16, /**< CHAOS Chaos [NC3] */
+ TNET_PROTO_UDP = 17, /**< UDP User Datagram [RFC768][JBP] */
+ TNET_PROTO_MUX = 18, /**< MUX Multiplexing [IEN90][JBP] */
+ TNET_PROTO_DCN_MEAS = 19, /**< DCN-MEAS DCN Measurement Subsystems [DLM1] */
+ TNET_PROTO_HMP = 20, /**< HMP Host Monitoring [RFC869][RH6] */
+ TNET_PROTO_PRM = 21, /**< PRM Packet Radio Measurement [ZSU] */
+ TNET_PROTO_XNS_IDP = 22, /**< XNS-IDP XEROX NS IDP [ETHERNET][XEROX] */
+ TNET_PROTO_TRUNK_1 = 23, /**< TRUNK-1 Trunk-1 [BWB6] */
+ TNET_PROTO_TRUNK_2 = 24, /**< TRUNK-2 Trunk-2 [BWB6] */
+ TNET_PROTO_LEAF_1 = 25, /**< LEAF-1 Leaf-1 [BWB6] */
+ TNET_PROTO_LEAF_2 = 26, /**< LEAF-2 Leaf-2 [BWB6] */
+ TNET_PROTO_RDP = 27, /**< RDP Reliable Data Protocol [RFC908][RH6] */
+ TNET_PROTO_IRTP = 28, /**< IRTP Internet Reliable Transaction [RFC938][TXM] */
+ TNET_PROTO_ISO_TP4 = 29, /**< ISO-TP4 ISO Transport Protocol Class 4 [RFC905][RC77] */
+ TNET_PROTO_NETBLT = 30, /**< NETBLT Bulk Data Transfer Protocol [RFC969][DDC1] */
+ TNET_PROTO_MFE_NSP = 31, /**< MFE-NSP MFE Network Services Protocol [MFENET][BCH2] */
+ TNET_PROTO_MERIT_INP = 32, /**< MERIT-INP MERIT Internodal Protocol [HWB] */
+ TNET_PROTO_DCCP = 33, /**< DCCP Datagram Congestion Control Protocol [RFC4340] */
+ TNET_PROTO_3PC = 34, /**< 3PC Third Party Connect Protocol [SAF3] */
+ TNET_PROTO_IDPR = 35, /**< IDPR Inter-Domain Policy Routing Protocol [MXS1] */
+ TNET_PROTO_XTP = 36, /**< XTP XTP [GXC] */
+ TNET_PROTO_DDP = 37, /**< DDP Datagram Delivery Protocol [WXC] */
+ TNET_PROTO_IDPR_CMTP = 38, /**< IDPR-CMTP IDPR Control Message Transport Proto [MXS1] */
+ TNET_PROTO_TP_PP = 39, /**< TP++ TP++ Transport Protocol [DXF] */
+ TNET_PROTO_IL = 40, /**< IL IL Transport Protocol [Presotto] */
+ TNET_PROTO_IPv6 = 41, /**< IPv6 Ipv6 [Deering] */
+ TNET_PROTO_SDRP = 42, /**< SDRP Source Demand Routing Protocol [DXE1] */
+ TNET_PROTO_IPv6_Route = 43, /**< IPv6-Route Routing Header for IPv6 [Deering] */
+ TNET_PROTO_IPv6_Frag = 44, /**< IPv6-Frag Fragment Header for IPv6 [Deering] */
+ TNET_PROTO_IDRP = 45, /**< IDRP Inter-Domain Routing Protocol [Hares] */
+ TNET_PROTO_RSVP = 46, /**< RSVP Reservation Protocol [Braden] */
+ TNET_PROTO_GRE = 47, /**< GRE General Routing Encapsulation [Li] */
+ TNET_PROTO_DSR = 48, /**< DSR Dynamic Source Routing Protocol [RFC4728] */
+ TNET_PROTO_BNA = 49, /**< BNA BNA [Salamon] */
+ TNET_PROTO_ESP = 50, /**< ESP Encap Security Payload [RFC4303] */
+ TNET_PROTO_AH = 51, /**< AH Authentication Header [RFC4302] */
+ TNET_PROTO_I_NLSP = 52, /**< I-NLSP Integrated Net Layer Security TUBA [GLENN] */
+ TNET_PROTO_SWIPE = 53, /**< SWIPE IP with Encryption [JI6] */
+ TNET_PROTO_NARP = 54, /**< NARP NBMA Address Resolution Protocol [RFC1735] */
+ TNET_PROTO_MOBILE = 55, /**< MOBILE IP Mobility [Perkins] */
+ TNET_PROTO_TLSP = 56, /**< TLSP Transport Layer Security Protocol [Oberg] using Kryptonet key management */
+ TNET_PROTO_SKIP = 57, /**< SKIP SKIP [Markson] */
+ TNET_PROTO_IPv6_ICMP = 58, /**< IPv6-ICMP ICMP for IPv6 [RFC1883] */
+ TNET_PROTO_IPv6_NoNxt = 59, /**< IPv6-NoNxt No Next Header for IPv6 [RFC1883] */
+ TNET_PROTO_IPv6_Opts = 60, /**< IPv6-Opts Destination Options for IPv6 [RFC1883] */
+ TNET_PROTO_ANY_INTERNAL = 61, /**< any host internal protocol [IANA] */
+ TNET_PROTO_CFTP = 62, /**< CFTP CFTP [CFTP][HCF2] */
+ TNET_PROTO_ANY_LOCAL = 63, /**< any local network [IANA] */
+ TNET_PROTO_SAT_EXPAK = 64, /**< SAT-EXPAK SATNET and Backroom EXPAK [SHB] */
+ TNET_PROTO_KRYPTOLAN = 65, /**< KRYPTOLAN Kryptolan [PXL1] */
+ TNET_PROTO_RVD = 66, /**< RVD MIT Remote Virtual Disk Protocol [MBG] */
+ TNET_PROTO_IPPC = 67, /**< IPPC Internet Pluribus Packet Core [SHB] */
+ TNET_PROTO_ANY_DISTRIBUTED = 68, /**< any distributed file system [IANA] */
+ TNET_PROTO_SAT_MON = 69, /**< SAT-MON SATNET Monitoring [SHB] */
+ TNET_PROTO_VISA = 70, /**< VISA VISA Protocol [GXT1] */
+ TNET_PROTO_IPCV = 71, /**< IPCV Internet Packet Core Utility [SHB] */
+ TNET_PROTO_CPNX = 72, /**< CPNX Computer Protocol Network Executive [DXM2] */
+ TNET_PROTO_CPHB = 73, /**< CPHB Computer Protocol Heart Beat [DXM2] */
+ TNET_PROTO_WSN = 74, /**< WSN Wang Span Network [VXD] */
+ TNET_PROTO_PVP = 75, /**< PVP Packet Video Protocol [SC3] */
+ TNET_PROTO_BR_SAT_MON = 76, /**< BR-SAT-MON Backroom SATNET Monitoring [SHB] */
+ TNET_PROTO_SUN_ND = 77, /**< SUN-ND SUN ND PROTOCOL-Temporary [WM3] */
+ TNET_PROTO_WB_MON = 78, /**< WB-MON WIDEBAND Monitoring [SHB] */
+ TNET_PROTO_WB_EXPAK = 79, /**< WB-EXPAK WIDEBAND EXPAK [SHB] */
+ TNET_PROTO_ISO_IP = 80, /**< ISO-IP ISO Internet Protocol [MTR] */
+ TNET_PROTO_VMTP = 81, /**< VMTP VMTP [DRC3] */
+ TNET_PROTO_SECURE_VMTP = 82, /**< SECURE-VMTP SECURE-VMTP [DRC3] */
+ TNET_PROTO_VINES = 83, /**< VINES VINES [BXH] */
+ TNET_PROTO_TTP = 84, /**< TTP TTP [JXS] */
+ TNET_PROTO_NSFNET_IGP = 85, /**< NSFNET-IGP NSFNET-IGP [HWB] */
+ TNET_PROTO_DGP = 86, /**< DGP Dissimilar Gateway Protocol [DGP][ML109] */
+ TNET_PROTO_TCF = 87, /**< TCF TCF [GAL5] */
+ TNET_PROTO_EIGRP = 88, /**< EIGRP EIGRP [CISCO][GXS] */
+ TNET_PROTO_OSPFIGP = 89, /**< OSPFIGP OSPFIGP [RFC1583][JTM4] */
+ TNET_PROTO_Sprite_RPC = 90, /**< Sprite-RPC Sprite RPC Protocol [SPRITE][BXW] */
+ TNET_PROTO_LARP = 91, /**< LARP Locus Address Resolution Protocol [BXH] */
+ TNET_PROTO_MTP = 92, /**< MTP Multicast Transport Protocol [SXA] */
+ TNET_PROTO_AX25 = 93, /**< AX.25 AX.25 Frames [BK29] */
+ TNET_PROTO_IPIP = 94, /**< IPIP IP-within-IP Encapsulation Protocol [JI6] */
+ TNET_PROTO_MICP = 95, /**< MICP Mobile Internetworking Control Pro. [JI6] */
+ TNET_PROTO_SCC_SP = 96, /**< SCC-SP Semaphore Communications Sec. Pro. [HXH] */
+ TNET_PROTO_ETHERIP = 97, /**< ETHERIP Ethernet-within-IP Encapsulation [RFC3378] */
+ TNET_PROTO_ENCAP = 98, /**< ENCAP Encapsulation Header [RFC1241,RXB3] */
+ TNET_PROTO_ANY_PRIV_ENC = 99, /**< any private encryption scheme [IANA] */
+ TNET_PROTO_GMTP = 100, /**< GMTP GMTP [RXB5] */
+ TNET_PROTO_IFMP = 101, /**< IFMP Ipsilon Flow Management Protocol [Hinden] */
+ TNET_PROTO_PNNI = 102, /**< PNNI PNNI over IP [Callon] */
+ TNET_PROTO_PIM = 103, /**< PIM Protocol Independent Multicast [Farinacci] */
+ TNET_PROTO_ARIS = 104, /**< ARIS ARIS [Feldman] */
+ TNET_PROTO_SCPS = 105, /**< SCPS SCPS [Durst] */
+ TNET_PROTO_QNX = 106, /**< QNX QNX [Hunter] */
+ TNET_PROTO_AN = 107, /**< A/N Active Networks [Braden] */
+ TNET_PROTO_IPComp = 108, /**< IPComp IP Payload Compression Protocol [RFC2393] */
+ TNET_PROTO_SNP = 109, /**< SNP Sitara Networks Protocol [Sridhar] */
+ TNET_PROTO_Compaq_Peer = 110, /**< Compaq-Peer Compaq Peer Protocol [Volpe] */
+ TNET_PROTO_IPX_in_IP = 11, /**< IPX-in-IP IPX in IP [Lee] */
+ TNET_PROTO_VRRP = 112, /**< VRRP Virtual Router Redundancy Protocol [RFC3768][RFC-ietf-vrrp-unified-spec-05.txt] */
+ TNET_PROTO_PGM = 113, /**< PGM PGM Reliable Transport Protocol [Speakman] */
+ TNET_PROTO_ANY_ZERO_HOP = 114, /**< any 0-hop protocol [IANA] */
+ TNET_PROTO_L2TP = 115, /**< L2TP Layer Two Tunneling Protocol [Aboba] */
+ TNET_PROTO_DDX = 116, /**< DDX D-II Data Exchange (DDX) [Worley] */
+ TNET_PROTO_IATP = 117, /**< IATP Interactive Agent Transfer Protocol [Murphy] */
+ TNET_PROTO_STP = 118, /**< STP Schedule Transfer Protocol [JMP] */
+ TNET_PROTO_SRP = 119, /**< SRP SpectraLink Radio Protocol [Hamilton] */
+ TNET_PROTO_UTI = 120, /**< UTI UTI [Lothberg] */
+ TNET_PROTO_SMP = 121, /**< SMP Simple Message Protocol [Ekblad] */
+ TNET_PROTO_SM = 122, /**< SM SM [Crowcroft] */
+ TNET_PROTO_PTP = 123, /**< PTP Performance Transparency Protocol [Welzl] */
+ TNET_PROTO_ISIS = 124, /**< ISIS over IPv4 [Przygienda] */
+ TNET_PROTO_FIRE = 125, /**< FIRE [Partridge] */
+ TNET_PROTO_CRTP = 126, /**< CRTP Combat Radio Transport Protocol [Sautter] */
+ TNET_PROTO_CRUDP = 127, /**< CRUDP Combat Radio User Datagram [Sautter] */
+ TNET_PROTO_SSCOPMCE = 128, /**< SSCOPMCE [Waber] */
+ TNET_PROTO_IPLT = 129, /**< IPLT [Hollbach] */
+ TNET_PROTO_SPS = 130, /**< SPS Secure Packet Shield [McIntosh] */
+ TNET_PROTO_PIPE = 131, /**< PIPE Private IP Encapsulation within IP [Petri] */
+ TNET_PROTO_SCTP = 132, /**< SCTP Stream Control Transmission Protocol [Stewart] */
+ TNET_PROTO_FC = 133, /**< FC Fibre Channel [Rajagopal] */
+ TNET_PROTO_RSVP_E2E_IGNORE = 134, /**< RSVP-E2E-IGNORE [RFC3175] */
+ TNET_PROTO_Mobility_Header = 135, /**< Mobility Header [RFC3775] */
+ TNET_PROTO_UDPLite = 136, /**< UDPLite [RFC3828] */
+ TNET_PROTO_MPLS_in_IP = 137, /**< MPLS-in-IP [RFC4023] */
+ TNET_PROTO_manet = 138, /**< manet MANET Protocols [RFC5498] */
+ TNET_PROTO_HIP = 139, /**< HIP Host Identity Protocol [RFC5201] */
+ TNET_PROTO_Shim6 = 140, /**< Shim6 Shim6 Protocol [RFC5533] */
+ //TNET_PROTO_ = 141-252 Unassigned [IANA]
+ TNET_PROTO_EXP1 = 253, /**< Use for experimentation and testing [RFC3692] */
+ TNET_PROTO_EXP2 = 254, /**< Use for experimentation and testing [RFC3692] */
+ TNET_PROTO_Reserved = 255, /**< Reserved [IANA] */
}
tnet_proto_t;
diff --git a/tinyNET/src/tnet_proxy_node_socks_plugin.c b/tinyNET/src/tnet_proxy_node_socks_plugin.c
index e5f8d08..f15f706 100755
--- a/tinyNET/src/tnet_proxy_node_socks_plugin.c
+++ b/tinyNET/src/tnet_proxy_node_socks_plugin.c
@@ -89,22 +89,21 @@ typedef enum socks5_state_e {
socks5_state_auth_req,
socks5_state_conn_req,
socks5_state_conn_accept,
-
+
socks5_state_error
}
socks5_state_t;
-typedef struct tnet_proxy_node_socks_plugin_s
-{
+typedef struct tnet_proxy_node_socks_plugin_s {
TNET_DECLARE_PROXY_NONE;
-
+
struct {
tsk_bool_t completed;
tsk_bool_t started;
tsk_buffer_t* buff;
uint8_t* pending_data_ptr;
tsk_size_t pending_data_len;
-
+
socks5_state_t socks5_state;
socks5_auth_method_t socks5_auth_method;
#if TNET_SOCKS5_HAVE_AUTH_GSSAPI
@@ -114,10 +113,10 @@ typedef struct tnet_proxy_node_socks_plugin_s
OM_uint32 status_major;
gss_name_t server_name;
tsk_bool_t init_sec_complete;
- }gss;
+ } gss;
#endif /* TNET_SOCKS5_HAVE_AUTH_GSSAPI */
} handshacking;
-
+
TSK_DECLARE_SAFEOBJ;
}
tnet_proxy_node_socks_plugin_t;
@@ -135,18 +134,18 @@ static int _tnet_proxy_node_socks_plugin_configure(tnet_proxy_node_t* self, ...)
tnet_proxy_node_socks_plugin_t* node = (tnet_proxy_node_socks_plugin_t*)self;
va_list ap;
int ret = 0;
-
+
// input parameters already checked by the caller
-
+
tsk_safeobj_lock(node);
-
+
// extract dst_host, dst_port, proxy_host, proxy_port, ipv6_enabled, ...
va_start(ap, self);
ret = tnet_proxy_node_configure_2(self, &ap);
va_end(ap);
-
+
tsk_safeobj_unlock(node);
-
+
return 0;
}
@@ -154,9 +153,9 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
{
tnet_proxy_node_socks_plugin_t* node = (tnet_proxy_node_socks_plugin_t*)self;
int ret = 0;
-
+
// input parameters already checked by the caller
-
+
tsk_safeobj_lock(node);
if (node->handshacking.started) {
TSK_DEBUG_ERROR("handshaking already started");
@@ -167,11 +166,11 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
ret = -2;
goto bail;
}
-
+
// reset pending data
TSK_FREE(node->handshacking.pending_data_ptr);
node->handshacking.pending_data_len = 0;
-
+
#if USING_CFSTREAM
if (tsk_strnullORempty(self->proxy_host) || !self->proxy_port) {
TSK_DEBUG_ERROR("Invalid proxy host and/or port for socks server %s:%hu", self->proxy_host, self->proxy_port);
@@ -183,7 +182,7 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
ret = -3;
goto bail;
}
-
+
CFStringRef cfstrHost = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, self->proxy_host, kCFStringEncodingUTF8, NULL);
int intPort = (int)self->proxy_port;
CFNumberRef cfintPort = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &intPort);
@@ -202,10 +201,10 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
CFDictionarySetValue(socksConfig, kCFStreamPropertySOCKSPassword, cfstrPassword);
CFRelease(cfstrPassword);
}
-
+
if (!CFReadStreamSetProperty(self->cf_read_stream, kCFStreamPropertySOCKSProxy, socksConfig)) {
CFStreamError error = CFReadStreamGetError(self->cf_read_stream);
-
+
TSK_DEBUG_INFO("CFReadStreamSetProperty(kCFStreamPropertySOCKSProxy) failed code=%d, domain=%ld", (int)error.error, error.domain);
ret = -4;
}
@@ -214,12 +213,12 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
TSK_DEBUG_INFO("CFWriteStreamSetProperty(kCFStreamPropertySOCKSProxy) code=%d, domain=%ld", (int)error.error, error.domain);
ret = -5;
}
-
+
CFRelease(cfstrHost);
CFRelease(cfintPort);
CFRelease(socksConfig);
CFRelease(proxyDict);
-
+
node->handshacking.started = (ret == 0);
node->handshacking.completed = node->handshacking.started; // no handshaking data to send, up to the system
#else
@@ -227,15 +226,15 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
tsk_size_t size_to_reserve, userid_len = tsk_strlen(self->login), domain_len = 0;
if (self->type == tnet_proxy_type_socks4 || self->type == tnet_proxy_type_socks4a) {
size_to_reserve = 1 /* version number */
- + 1 /* command code */
- + 2 /* network byte order port number */
- + 4 /* network byte order IP address */
- + userid_len + 1 /* the user ID string, variable length, terminated with a null (0x00) */
- ;
+ + 1 /* command code */
+ + 2 /* network byte order port number */
+ + 4 /* network byte order IP address */
+ + userid_len + 1 /* the user ID string, variable length, terminated with a null (0x00) */
+ ;
if (self->type == tnet_proxy_type_socks4a) {
domain_len = tsk_strlen(self->dst_host);
size_to_reserve += domain_len + 1/* the domain name of the host we want to contact, variable length, terminated with a null (0x00) */
- ;
+ ;
}
}
else { // SOCKS5
@@ -246,17 +245,17 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
}
// Greeting
size_to_reserve = 1 /* version number */
- + 1 /* number of authentication methods supported */
+ + 1 /* number of authentication methods supported */
#if TNET_SOCKS5_HAVE_AUTH_NONE
- + 1
+ + 1
#endif
#if TNET_SOCKS5_HAVE_AUTH_USRPWD
- + 1
+ + 1
#endif
#if TNET_SOCKS5_HAVE_AUTH_GSSAPI
- + 1
+ + 1
#endif
- ;
+ ;
}
node->handshacking.pending_data_ptr = (uint8_t*)tsk_realloc(node->handshacking.pending_data_ptr, size_to_reserve);
if (!node->handshacking.pending_data_ptr) {
@@ -266,7 +265,7 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
goto bail;
}
node->handshacking.pending_data_len = size_to_reserve;
-
+
if (self->type == tnet_proxy_type_socks4 || self->type == tnet_proxy_type_socks4a) {
node->handshacking.pending_data_ptr[0] = 0x04; // version number
node->handshacking.pending_data_ptr[1] = 0x01; // establish a TCP/IP stream connection (caller aldready check we're dealing with Streams)
@@ -294,7 +293,7 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
memcpy(&node->handshacking.pending_data_ptr[8], self->login, userid_len);
}
node->handshacking.pending_data_ptr[8 + userid_len] = 0x00;
-
+
// the domain name of the host we want to contact, variable length, terminated with a null (0x00)
if (self->type == tnet_proxy_type_socks4a) {
if (domain_len > 0) {
@@ -331,8 +330,8 @@ static int _tnet_proxy_node_socks_plugin_start_handshaking(tnet_proxy_node_t* se
node->handshacking.started = tsk_true;
}
#endif
-
-
+
+
bail:
tsk_safeobj_unlock(node);
return ret;
@@ -342,17 +341,17 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
{
tnet_proxy_node_socks_plugin_t* node = (tnet_proxy_node_socks_plugin_t*)self;
int ret = 0;
-
+
// input parameters already checked by the caller
-
+
tsk_safeobj_lock(node);
-
+
if (!node->handshacking.started) {
TSK_DEBUG_ERROR("handshaking not started");
ret = -3;
goto bail;
}
-
+
#if USING_CFSTREAM
TSK_DEBUG_ERROR("Up to CFStreams to handle handshaking");
ret = -2;
@@ -400,7 +399,8 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
}
if (buff[0] != 0x05) {
TSK_DEBUG_ERROR("Invalid version (%d)", buff[0]);
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
if (buff[1] == kSocks5AuthMethodNone || buff[1] == kSocks5AuthMethodUsrPwd || buff[1] == kSocks5AuthMethodGSSAPI) {
node->handshacking.socks5_auth_method = (socks5_auth_method_t)buff[1];
@@ -410,16 +410,17 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
node->handshacking.socks5_state = socks5_state_conn_req;
// FIXME:
TSK_DEBUG_ERROR("Not implemented yet");
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
else {
if (node->handshacking.socks5_auth_method == kSocks5AuthMethodUsrPwd) {
tsk_size_t userlen = tsk_strlen(self->login), pwdlen = tsk_strlen(self->password);
tsk_size_t size_to_reserve = 1 /* version number */
- + 1 /* username length */
- + userlen /* username */
- + 1 /* password length */
- + pwdlen;
+ + 1 /* username length */
+ + userlen /* username */
+ + 1 /* password length */
+ + pwdlen;
node->handshacking.pending_data_ptr = (uint8_t*)tsk_realloc(node->handshacking.pending_data_ptr, size_to_reserve);
if (!node->handshacking.pending_data_ptr) {
TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", (unsigned)size_to_reserve);
@@ -428,7 +429,7 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
goto bail;
}
node->handshacking.pending_data_len = size_to_reserve;
-
+
node->handshacking.pending_data_ptr[0] = 0x01;
node->handshacking.pending_data_ptr[1] = (userlen & 0xFF);
if (userlen > 0) {
@@ -450,21 +451,24 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
TSK_DEBUG_ERROR("gss_import_name() failed");
goto bail;
}
-
+
#else
TSK_DEBUG_ERROR("GSSAPI not supported");
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
#endif
}
else {
TSK_DEBUG_ERROR("Not implemented yet");
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
}
}
else {
TSK_DEBUG_ERROR("Invalid authentication method (%d)", buff[1]);
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
}
else if (node->handshacking.socks5_state == socks5_state_auth_req) {
@@ -476,12 +480,14 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
}
if (buff[0] != 0x1) {
TSK_DEBUG_ERROR("Invalid version :%d", buff[0]);
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
TSK_DEBUG_INFO("Socks5 authentication status code: %d", buff[1]);
if (buff[1] != 0x00) {
TSK_DEBUG_ERROR("Authentication failed with status code :%d", buff[1]);
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
tsk_buffer_remove(node->handshacking.buff, 0, 2); // remove parsed bytes
node->handshacking.socks5_state = socks5_state_conn_req;
@@ -489,13 +495,15 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
else if (node->handshacking.socks5_auth_method == kSocks5AuthMethodGSSAPI) {
// FIXME:
TSK_DEBUG_ERROR("Not implemented yet");
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
else {
TSK_DEBUG_ERROR("Invalid authentication method (%d)", buff[1]);
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
-
+
// State changed from "auth_req" to "conn_req" : build connection request
if (node->handshacking.socks5_state == socks5_state_conn_req) {
#define kAddrTypeIPv4 0x01
@@ -505,12 +513,12 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
tsk_bool_t is_ip = tsk_false; // ip or domain name
uint8_t addr_type = 0x00;
tsk_size_t dst_addr_len = 0, size_to_reserve = 1 /* version number */
- + 1 /* command code */
- + 1 /* reserved, must be 0x00 */
- + 1 /* address type */
- + 0 /* destination address (==to be computed later==) */
- + 2 /* port number in a network byte order */
- ;
+ + 1 /* command code */
+ + 1 /* reserved, must be 0x00 */
+ + 1 /* address type */
+ + 0 /* destination address (==to be computed later==) */
+ + 2 /* port number in a network byte order */
+ ;
if ((ret = tnet_sockaddr_init(self->dst_host, self->dst_port, self->socket.type, &addr)) != 0) {
TSK_DEBUG_WARN("tnet_sockaddr_init(%s, %d, %d) failed", self->dst_host, self->dst_port, self->socket.type);
// maybe DNS issue (e.g UDP blocked), do not exit, up to the server to resolve it
@@ -534,10 +542,11 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
if (!node->handshacking.pending_data_ptr) {
TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", (unsigned)size_to_reserve);
node->handshacking.pending_data_len = 0;
- ret = -5; goto bail;
+ ret = -5;
+ goto bail;
}
node->handshacking.pending_data_len = size_to_reserve;
-
+
node->handshacking.pending_data_ptr[0] = 0x05; // version number
node->handshacking.pending_data_ptr[1] = 0x01; // establish a TCP/IP stream connection
node->handshacking.pending_data_ptr[2] = 0x00; // reserved, must be 0x00
@@ -564,12 +573,14 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
}
if (buff[0] != 0x05) {
TSK_DEBUG_ERROR("Invalid version (%d)", buff[0]);
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
TSK_DEBUG_INFO("Socks5 connection request status code: %d", buff[1]);
if (buff[1] != 0x00) {
TSK_DEBUG_ERROR("Socks5 connection request failed with status code :%d", buff[1]);
- ret = -3; goto bail;
+ ret = -3;
+ goto bail;
}
tsk_buffer_remove(node->handshacking.buff, 0, 2); // remove parsed bytes
node->handshacking.socks5_state = socks5_state_conn_accept;
@@ -592,7 +603,7 @@ static int _tnet_proxy_node_socks_plugin_set_handshaking_data(tnet_proxy_node_t*
goto bail;
}
#endif
-
+
bail:
if (ret != 0) {
if (self->type == tnet_proxy_type_socks5) {
@@ -607,11 +618,11 @@ static int _tnet_proxy_node_socks_plugin_get_handshaking_pending_data(tnet_proxy
{
tnet_proxy_node_socks_plugin_t* node = (tnet_proxy_node_socks_plugin_t*)self;
int ret = -1;
-
+
// input parameters already checked by the caller
-
+
tsk_safeobj_lock(node);
-
+
#if USING_CFSTREAM
*data_psize = 0; // no pending data
ret = 0;
@@ -627,7 +638,7 @@ static int _tnet_proxy_node_socks_plugin_get_handshaking_pending_data(tnet_proxy
node->handshacking.pending_data_len = 0;
}
#endif
-
+
tsk_safeobj_unlock(node);
return ret;
}
@@ -636,9 +647,9 @@ static int _tnet_proxy_node_socks_plugin_get_handshaking_completed(tnet_proxy_no
{
tnet_proxy_node_socks_plugin_t* node = (tnet_proxy_node_socks_plugin_t*)self;
int ret = 0;
-
+
// input parameters already checked by the caller
-
+
tsk_safeobj_lock(node);
*completed = node->handshacking.completed;
tsk_safeobj_unlock(node);
@@ -648,23 +659,34 @@ static int _tnet_proxy_node_socks_plugin_get_handshaking_completed(tnet_proxy_no
static const char* __socks5_state_to_string(socks5_state_t state)
{
switch (state) {
- case socks5_state_none: return "none";
- case socks5_state_greeting: return "greeting";
- case socks5_state_auth_req: return "auth_req";
- case socks5_state_conn_req: return "conn_req";
- case socks5_state_conn_accept: return "conn_accept";
- case socks5_state_error: return "error";
- default: return "unknown";
+ case socks5_state_none:
+ return "none";
+ case socks5_state_greeting:
+ return "greeting";
+ case socks5_state_auth_req:
+ return "auth_req";
+ case socks5_state_conn_req:
+ return "conn_req";
+ case socks5_state_conn_accept:
+ return "conn_accept";
+ case socks5_state_error:
+ return "error";
+ default:
+ return "unknown";
}
}
static const char* __socks5_method_to_string(socks5_auth_method_t method)
{
switch (method) {
- case kSocks5AuthMethodNone: return "none";
- case kSocks5AuthMethodGSSAPI: return "gssapi";
- case kSocks5AuthMethodUsrPwd: return "usr/pwd";
- default: return "unknown";
+ case kSocks5AuthMethodNone:
+ return "none";
+ case kSocks5AuthMethodGSSAPI:
+ return "gssapi";
+ case kSocks5AuthMethodUsrPwd:
+ return "usr/pwd";
+ default:
+ return "unknown";
}
}
@@ -676,7 +698,7 @@ static int __socks5_gss_import_name(tnet_proxy_node_t* self)
int i, ret = 0;
tnet_proxy_node_socks_plugin_t* node = (tnet_proxy_node_socks_plugin_t*)self;
gss_buffer_desc input_name_buffer = GSS_C_EMPTY_BUFFER;
-
+
if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
@@ -686,7 +708,7 @@ static int __socks5_gss_import_name(tnet_proxy_node_t* self)
// reset pending handshaking data
TSK_FREE(node->handshacking.pending_data_ptr);
node->handshacking.pending_data_len = 0;
-
+
/*
For example, when using Kerberos V5 naming, the imported name may be
of the form "SERVICE:socks@socks_server_hostname" where
@@ -697,7 +719,7 @@ static int __socks5_gss_import_name(tnet_proxy_node_t* self)
for (i = 0; i < input_name_buffer.length; ++i) {
((char*)input_name_buffer.value)[i] = tolower(((char*)input_name_buffer.value)[i]);
}
-
+
/*
The client should call gss_import_name to obtain an internal
representation of the server name. For maximal portability the
@@ -709,19 +731,20 @@ static int __socks5_gss_import_name(tnet_proxy_node_t* self)
TSK_DEBUG_INFO("gss_import_name(%.*s, GSS_C_NULL_OID): minor_status = %u, major_status = %u", (int)input_name_buffer.length, (const char*)input_name_buffer.value, node->handshacking.gss.status_minor, node->handshacking.gss.status_major);
if (node->handshacking.gss.status_major != GSS_S_COMPLETE) {
__socks_gss_print_error("gss_import_name failed", node->handshacking.gss.status_major, node->handshacking.gss.status_minor);
- ret = -2; goto bail;
+ ret = -2;
+ goto bail;
}
/* debug */{
gss_OID output_name_type;
gss_buffer_desc output_name = GSS_C_EMPTY_BUFFER;
node->handshacking.gss.status_major = gss_display_name(&node->handshacking.gss.status_minor,
- node->handshacking.gss.server_name,
- &output_name,
- &output_name_type);
+ node->handshacking.gss.server_name,
+ &output_name,
+ &output_name_type);
TSK_DEBUG_INFO("gss_display_name(%.*s): minor_status = %u, major_status = %u, output = %.*s", (int)input_name_buffer.length, (const char*)input_name_buffer.value, node->handshacking.gss.status_minor, node->handshacking.gss.status_major, (int)output_name.length, (const char*)output_name.value);
node->handshacking.gss.status_major = gss_release_buffer(&node->handshacking.gss.status_minor, &output_name);
}
-
+
bail:
gss_release_buffer(&node->handshacking.gss.status_minor, &input_name_buffer);
return 0;
@@ -736,17 +759,17 @@ static int __socks5_gss_init_sec_context(tnet_proxy_node_t* self)
tnet_proxy_node_socks_plugin_t* node = (tnet_proxy_node_socks_plugin_t*)self;
gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER, *input_token_ptr = GSS_C_NO_BUFFER;
gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
-
-/*
- +------+------+------+.......................+
- + ver | mtyp | len | token |
- +------+------+------+.......................+
- + 0x01 | 0x01 | 0x02 | up to 2^16 - 1 octets |
- +------+------+------+.......................+
-*/
+
+ /*
+ +------+------+------+.......................+
+ + ver | mtyp | len | token |
+ +------+------+------+.......................+
+ + 0x01 | 0x01 | 0x02 | up to 2^16 - 1 octets |
+ +------+------+------+.......................+
+ */
#define kTokenMsgHdrLongLen 4 // with "len" field
#define kTokenMsgHdrShortLen 2 // without "len" field
-
+
if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
@@ -766,44 +789,46 @@ static int __socks5_gss_init_sec_context(tnet_proxy_node_t* self)
}
else {
TSK_DEBUG_ERROR("GSS invalid mtyp(%u)", buff[1]);
- ret = -5; goto bail;
+ ret = -5;
+ goto bail;
}
}
-
+
req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_DELEG_FLAG;
// However, GSS_C_SEQUENCE_FLAG should only be passed in for TCP-based clients, not for UDP-based clients.
if (TNET_SOCKET_TYPE_IS_STREAM(self->socket.type)) {
req_flags |= GSS_C_SEQUENCE_FLAG;
}
-
+
node->handshacking.gss.status_major = gss_delete_sec_context(&node->handshacking.gss.status_minor, &node->handshacking.gss.ctx, NULL);
-
+
node->handshacking.gss.ctx = GSS_C_NO_CONTEXT;
node->handshacking.gss.status_major = gss_init_sec_context(&node->handshacking.gss.status_minor,
- GSS_C_NO_CREDENTIAL, // GSS_C_NO_CREDENTIAL into cred_handle to specify the default credential (for initiator usage)
- &node->handshacking.gss.ctx,
- node->handshacking.gss.server_name,
- GSS_C_NULL_OID, // GSS_C_NULL_OID into mech_type to specify the default mechanism
- req_flags,
- GSS_C_INDEFINITE,
- GSS_C_NO_CHANNEL_BINDINGS,
- input_token_ptr,
- tsk_null,
- &output_token,
- tsk_null,
- tsk_null);
-
-
+ GSS_C_NO_CREDENTIAL, // GSS_C_NO_CREDENTIAL into cred_handle to specify the default credential (for initiator usage)
+ &node->handshacking.gss.ctx,
+ node->handshacking.gss.server_name,
+ GSS_C_NULL_OID, // GSS_C_NULL_OID into mech_type to specify the default mechanism
+ req_flags,
+ GSS_C_INDEFINITE,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ input_token_ptr,
+ tsk_null,
+ &output_token,
+ tsk_null,
+ tsk_null);
+
+
// Only "GSS_S_COMPLETE" and "GSS_S_CONTINUE_NEEDED" are acceptable
if (node->handshacking.gss.status_major != GSS_S_COMPLETE && node->handshacking.gss.status_major != GSS_S_CONTINUE_NEEDED) {
__socks_gss_print_error("gss_init_sec_context failed", node->handshacking.gss.status_major, node->handshacking.gss.status_minor);
- ret = -2; goto bail;
+ ret = -2;
+ goto bail;
}
-
+
// reset pending handshaking data
TSK_FREE(node->handshacking.pending_data_ptr);
node->handshacking.pending_data_len = 0;
-
+
if (output_token.length > 0 && output_token.value) {
node->handshacking.pending_data_len = kTokenMsgHdrLongLen + output_token.length;
node->handshacking.pending_data_ptr = tsk_realloc(node->handshacking.pending_data_ptr, node->handshacking.pending_data_len);
@@ -819,14 +844,14 @@ static int __socks5_gss_init_sec_context(tnet_proxy_node_t* self)
node->handshacking.pending_data_ptr[3] = output_token.length & 0xFF;
memcpy(&node->handshacking.pending_data_ptr[4], output_token.value, output_token.length);
}
-
+
if (input_token.length > 0) {
tsk_buffer_remove(node->handshacking.buff, 0, kTokenMsgHdrLongLen + input_token.length);
}
-
+
// update "init_sec_complete"
node->handshacking.gss.init_sec_complete = (ret == 0) && (node->handshacking.gss.status_major == GSS_S_COMPLETE);
-
+
bail:
return ret;
}
@@ -835,7 +860,7 @@ static void __socks_gss_print_error(const char* info, OM_uint32 status_major, OM
{
OM_uint32 m1, m2, s1, s2;
gss_buffer_desc out1 = {.value = tsk_null, .length = 0}, out2 = {.value = tsk_null, .length = 0};
-
+
// print the error
m1 = 0, s1 = 0;
gss_display_status(&s1, status_major, GSS_C_GSS_CODE, GSS_C_NULL_OID, &m1, &out1);
@@ -885,29 +910,27 @@ static tsk_object_t* tnet_proxy_node_socks_plugin_dtor(tsk_object_t * self)
}
#endif /* TNET_SOCKS5_HAVE_AUTH_GSSAPI */
tsk_safeobj_deinit(node);
-
+
TSK_DEBUG_INFO("*** Socks(4/4a/5) proxy node destroyed ***");
}
return self;
}
/* object definition */
-static const tsk_object_def_t thttp_proxy_node_def_s =
-{
+static const tsk_object_def_t thttp_proxy_node_def_s = {
sizeof(tnet_proxy_node_socks_plugin_t),
tnet_proxy_node_socks_plugin_ctor,
tnet_proxy_node_socks_plugin_dtor,
tsk_null,
};
/* plugin definition*/
-static const struct tnet_proxy_node_plugin_def_s tnet_proxy_node_socks_plugin_def_s =
-{
+static const struct tnet_proxy_node_plugin_def_s tnet_proxy_node_socks_plugin_def_s = {
&thttp_proxy_node_def_s,
-
+
(tnet_proxy_type_socks4 | tnet_proxy_type_socks4a | tnet_proxy_type_socks5),
-
+
"SOCKS(4/4a/5) proxy node plugin",
-
+
_tnet_proxy_node_socks_plugin_configure,
_tnet_proxy_node_socks_plugin_start_handshaking,
_tnet_proxy_node_socks_plugin_set_handshaking_data,
diff --git a/tinyNET/src/tnet_proxy_plugin.c b/tinyNET/src/tnet_proxy_plugin.c
index dbcd143..1555dce 100755
--- a/tinyNET/src/tnet_proxy_plugin.c
+++ b/tinyNET/src/tnet_proxy_plugin.c
@@ -34,17 +34,17 @@ const tnet_proxy_node_plugin_def_t* __tnet_proxy_node_plugins[TNET_PROXY_NODE_MA
tsk_bool_t tnet_proxy_node_is_nettransport_supported(enum tnet_proxy_type_e proxy_type, enum tnet_socket_type_e socket_type)
{
switch (proxy_type) {
- case tnet_proxy_type_http:
+ case tnet_proxy_type_http:
case tnet_proxy_type_https:
- return TNET_SOCKET_TYPE_IS_STREAM(socket_type);
-
- case tnet_proxy_type_socks4:
- case tnet_proxy_type_socks4a:
- return TNET_SOCKET_TYPE_IS_STREAM(socket_type) && TNET_SOCKET_TYPE_IS_IPV4(socket_type);
- case tnet_proxy_type_socks5: // SOCKS5 adds support for UDP and IPv6
- return TNET_SOCKET_TYPE_IS_STREAM(socket_type) || TNET_SOCKET_TYPE_IS_DGRAM(socket_type);// for now we don't support socks for UDP (just like a browser)
- default:
- return tsk_false;
+ return TNET_SOCKET_TYPE_IS_STREAM(socket_type);
+
+ case tnet_proxy_type_socks4:
+ case tnet_proxy_type_socks4a:
+ return TNET_SOCKET_TYPE_IS_STREAM(socket_type) && TNET_SOCKET_TYPE_IS_IPV4(socket_type);
+ case tnet_proxy_type_socks5: // SOCKS5 adds support for UDP and IPv6
+ return TNET_SOCKET_TYPE_IS_STREAM(socket_type) || TNET_SOCKET_TYPE_IS_DGRAM(socket_type);// for now we don't support socks for UDP (just like a browser)
+ default:
+ return tsk_false;
}
}
@@ -61,12 +61,12 @@ int tnet_proxy_node_configure(tnet_proxy_node_t* self, ...)
{
va_list ap;
int ret = 0;
-
+
if (!self) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
va_start(ap, self);
ret = tnet_proxy_node_configure_2(self, &ap);
va_end(ap);
@@ -77,73 +77,81 @@ int tnet_proxy_node_configure_2(tnet_proxy_node_t* self, va_list* app)
{
int ret = 0;
tnet_proxy_node_param_type_t ptype;
-
+
if (!self || !app) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
while ((ptype = va_arg(*app, tnet_proxy_node_param_type_t)) != tnet_proxy_node_param_type_null) {
switch (ptype) {
- case tnet_proxy_node_param_type_destination_address:
- case tnet_proxy_node_param_type_proxy_address: {
- // (const char*)(HOST_STR), (int)(PORT_INT)
- const char* HOST_STR = va_arg(*app, const char*);
- int PORT_INT = va_arg(*app, int);
- if (PORT_INT < 1 || PORT_INT > 0xFFF) {
- TSK_DEBUG_ERROR("Invalid value for port number: %d", PORT_INT);
- ret = -3;
- goto bail;
- }
- if (ptype == tnet_proxy_node_param_type_destination_address) {
- tsk_strupdate(&self->dst_host, HOST_STR);
- self->dst_port = (tnet_port_t)PORT_INT;
- }
- else {
- tsk_strupdate(&self->proxy_host, HOST_STR);
- self->proxy_port = (tnet_port_t)PORT_INT;
- }
- break;
+ case tnet_proxy_node_param_type_destination_address:
+ case tnet_proxy_node_param_type_proxy_address: {
+ // (const char*)(HOST_STR), (int)(PORT_INT)
+ const char* HOST_STR = va_arg(*app, const char*);
+ int PORT_INT = va_arg(*app, int);
+ if (PORT_INT < 1 || PORT_INT > 0xFFF) {
+ TSK_DEBUG_ERROR("Invalid value for port number: %d", PORT_INT);
+ ret = -3;
+ goto bail;
}
- case tnet_proxy_node_param_type_ipv6: {
- /* (tsk_bool_t)(IPV6_BOOL) */
- self->ipv6 = va_arg(*app, tsk_bool_t);
- break;
+ if (ptype == tnet_proxy_node_param_type_destination_address) {
+ tsk_strupdate(&self->dst_host, HOST_STR);
+ self->dst_port = (tnet_port_t)PORT_INT;
}
- case tnet_proxy_node_param_type_credentials: {
- /* (const char*)(LOGIN_STR), (const char*)(PASSWORD_STR) */
- const char* LOGIN_STR = va_arg(*app, const char*);
- const char* PASSWORD_STR = va_arg(*app, const char*);
- tsk_strupdate(&self->login, LOGIN_STR);
- tsk_strupdate(&self->password, PASSWORD_STR);
- break;
- }
- case tnet_proxy_node_param_type_socket: {
- /* (tnet_fd_t)(FD_FD), (enum tnet_socket_type_e)(type) */
- self->socket.fd = va_arg(*app, tnet_fd_t);
- self->socket.type = va_arg(*app, enum tnet_socket_type_e);
- break;
+ else {
+ tsk_strupdate(&self->proxy_host, HOST_STR);
+ self->proxy_port = (tnet_port_t)PORT_INT;
}
+ break;
+ }
+ case tnet_proxy_node_param_type_ipv6: {
+ /* (tsk_bool_t)(IPV6_BOOL) */
+ self->ipv6 = va_arg(*app, tsk_bool_t);
+ break;
+ }
+ case tnet_proxy_node_param_type_credentials: {
+ /* (const char*)(LOGIN_STR), (const char*)(PASSWORD_STR) */
+ const char* LOGIN_STR = va_arg(*app, const char*);
+ const char* PASSWORD_STR = va_arg(*app, const char*);
+ tsk_strupdate(&self->login, LOGIN_STR);
+ tsk_strupdate(&self->password, PASSWORD_STR);
+ break;
+ }
+ case tnet_proxy_node_param_type_socket: {
+ /* (tnet_fd_t)(FD_FD), (enum tnet_socket_type_e)(type) */
+ self->socket.fd = va_arg(*app, tnet_fd_t);
+ self->socket.type = va_arg(*app, enum tnet_socket_type_e);
+ break;
+ }
#if TNET_UNDER_APPLE
- case tnet_proxy_node_param_type_cfstreams: {
- /* (CFReadStreamRef)(READ_CFSTREAM), (CFWriteStreamRef)(WRITE_CFSTREAM) */
- CFReadStreamRef READ_CFSTREAM = va_arg(*app, CFReadStreamRef);
- CFWriteStreamRef WRITE_CFSTREAM = va_arg(*app, CFWriteStreamRef);
- if (self->cf_read_stream) CFRelease(self->cf_read_stream), self->cf_read_stream = tsk_null;
- if (self->cf_write_stream) CFRelease(self->cf_write_stream), self->cf_write_stream = tsk_null;
- if (READ_CFSTREAM) self->cf_read_stream = (CFReadStreamRef)CFRetain(READ_CFSTREAM);
- if (WRITE_CFSTREAM) self->cf_write_stream = (CFWriteStreamRef)CFRetain(WRITE_CFSTREAM);
- break;
+ case tnet_proxy_node_param_type_cfstreams: {
+ /* (CFReadStreamRef)(READ_CFSTREAM), (CFWriteStreamRef)(WRITE_CFSTREAM) */
+ CFReadStreamRef READ_CFSTREAM = va_arg(*app, CFReadStreamRef);
+ CFWriteStreamRef WRITE_CFSTREAM = va_arg(*app, CFWriteStreamRef);
+ if (self->cf_read_stream) {
+ CFRelease(self->cf_read_stream), self->cf_read_stream = tsk_null;
}
-#endif /* TNET_UNDER_APPLE */
- default: {
- TSK_DEBUG_ERROR("%d not valid param type", ptype);
- ret = -2;
- goto bail;
+ if (self->cf_write_stream) {
+ CFRelease(self->cf_write_stream), self->cf_write_stream = tsk_null;
+ }
+ if (READ_CFSTREAM) {
+ self->cf_read_stream = (CFReadStreamRef)CFRetain(READ_CFSTREAM);
}
+ if (WRITE_CFSTREAM) {
+ self->cf_write_stream = (CFWriteStreamRef)CFRetain(WRITE_CFSTREAM);
+ }
+ break;
+ }
+#endif /* TNET_UNDER_APPLE */
+ default: {
+ TSK_DEBUG_ERROR("%d not valid param type", ptype);
+ ret = -2;
+ goto bail;
+ }
}
}
-
+
bail:
return ret;
}
@@ -210,16 +218,16 @@ int tnet_proxy_node_plugin_register(const tnet_proxy_node_plugin_def_t* plugin)
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
/* add or replace the plugin */
for (i = 0; i<TNET_PROXY_NODE_MAX_PLUGINS; i++) {
- if (!__tnet_proxy_node_plugins[i] || (__tnet_proxy_node_plugins[i] == plugin)){
+ if (!__tnet_proxy_node_plugins[i] || (__tnet_proxy_node_plugins[i] == plugin)) {
__tnet_proxy_node_plugins[i] = plugin;
TSK_DEBUG_INFO("Register network proxy node plugin: %s", plugin->desc);
return 0;
}
}
-
+
TSK_DEBUG_ERROR("There are already %d network proxy node plugins.", TNET_PROXY_NODE_MAX_PLUGINS);
return -2;
}
@@ -232,7 +240,7 @@ int tnet_proxy_node_plugin_unregister(const tnet_proxy_node_plugin_def_t* plugin
TSK_DEBUG_ERROR("Invalid Parameter");
return -1;
}
-
+
/* find the plugin to unregister */
for (i = 0; i<TNET_PROXY_NODE_MAX_PLUGINS && __tnet_proxy_node_plugins[i]; i++) {
if (__tnet_proxy_node_plugins[i] == plugin) {
@@ -242,7 +250,7 @@ int tnet_proxy_node_plugin_unregister(const tnet_proxy_node_plugin_def_t* plugin
break;
}
}
-
+
/* compact */
if (found) {
for (; i<(TNET_PROXY_NODE_MAX_PLUGINS - 1); i++) {
@@ -262,8 +270,8 @@ tsk_size_t tnet_proxy_node_plugin_registry_count()
{
tsk_size_t count;
for(count = 0;
- count < TNET_PROXY_NODE_MAX_PLUGINS && __tnet_proxy_node_plugins[count];
- ++count) ;
+ count < TNET_PROXY_NODE_MAX_PLUGINS && __tnet_proxy_node_plugins[count];
+ ++count) ;
return count;
}
diff --git a/tinyNET/src/tnet_proxy_plugin.h b/tinyNET/src/tnet_proxy_plugin.h
index 0a247bc..75d9612 100755
--- a/tinyNET/src/tnet_proxy_plugin.h
+++ b/tinyNET/src/tnet_proxy_plugin.h
@@ -35,7 +35,7 @@ TNET_BEGIN_DECLS
typedef struct tnet_proxy_node_s {
TSK_DECLARE_OBJECT;
-
+
enum tnet_proxy_type_e type;
tsk_bool_t ipv6;
char* dst_host;
@@ -52,7 +52,7 @@ typedef struct tnet_proxy_node_s {
CFReadStreamRef cf_read_stream;
CFWriteStreamRef cf_write_stream;
#endif /* TNET_UNDER_APPLE */
-
+
const struct tnet_proxy_node_plugin_def_s* plugin;
}
tnet_proxy_node_t;
@@ -60,8 +60,7 @@ tnet_proxy_node_t;
#define TNET_PROXY_NODE(self) ((tnet_proxy_node_t*)(self))
#define TNET_DECLARE_PROXY_NONE tnet_proxy_node_t __node__
-typedef enum tnet_proxy_node_param_type_e
-{
+typedef enum tnet_proxy_node_param_type_e {
tnet_proxy_node_param_type_null = 0,
tnet_proxy_node_param_type_destination_address,
tnet_proxy_node_param_type_proxy_address,
@@ -85,17 +84,16 @@ tnet_proxy_node_param_type_t;
#endif /* TNET_UNDER_APPLE */
/** Virtual table used to define a proxy node plugin */
-typedef struct tnet_proxy_node_plugin_def_s
-{
+typedef struct tnet_proxy_node_plugin_def_s {
//! object definition used to create an instance of the plugin
const tsk_object_def_t* objdef;
-
+
//! plugin type
enum tnet_proxy_type_e type;
-
+
//! full description (usefull for debugging)
const char* desc;
-
+
int (* configure) (tnet_proxy_node_t* self, ...);
int (* start_handshaking) (tnet_proxy_node_t* self);
int (* set_handshaking_data) (tnet_proxy_node_t* self, const void* data_ptr, tsk_size_t data_size);
diff --git a/tinyNET/src/tnet_proxydetect.c b/tinyNET/src/tnet_proxydetect.c
index 162985c..af0bec7 100755
--- a/tinyNET/src/tnet_proxydetect.c
+++ b/tinyNET/src/tnet_proxydetect.c
@@ -29,29 +29,28 @@ static tsk_object_t* _tnet_proxyinfo_ctor(tsk_object_t * self, va_list * app)
{
tnet_proxyinfo_t *info = (tnet_proxyinfo_t *)self;
if (info) {
-
+
}
return self;
}
static tsk_object_t* _tnet_proxyinfo_dtor(tsk_object_t * self)
{
tnet_proxyinfo_t *info = (tnet_proxyinfo_t *)self;
- if (info){
+ if (info) {
TSK_FREE(info->autoconfig_url);
TSK_FREE(info->bypass_list);
TSK_FREE(info->hostname);
TSK_FREE(info->username);
TSK_FREE(info->password);
}
-
+
return self;
}
-static const tsk_object_def_t tnet_proxyinfo_def_s =
-{
+static const tsk_object_def_t tnet_proxyinfo_def_s = {
sizeof(tnet_proxyinfo_t),
_tnet_proxyinfo_ctor,
_tnet_proxyinfo_dtor,
- tsk_null,
+ tsk_null,
};
const tsk_object_def_t *tnet_proxyinfo_def_t = &tnet_proxyinfo_def_s;
@@ -62,7 +61,7 @@ tnet_proxyinfo_t* tnet_proxyinfo_create()
TSK_DEBUG_ERROR("Failed to creatr 'tnet_proxyinfo_t' instance");
return info;
}
-
+
return info;
}
@@ -121,7 +120,7 @@ tnet_proxyinfo_t* tnet_proxydetect_get_info(const char* url, tnet_socket_type_t
TSK_DEBUG_ERROR("CFNetworkCopySystemProxySettings returned nil");
goto resolve_done;
}
-
+
cfProxies = CFNetworkCopyProxiesForURL(cfTargetUrl, cfProxySettings);
if (!cfProxies) {
TSK_DEBUG_ERROR("CFNetworkCopyProxiesForURL returned 0-array");
@@ -129,8 +128,8 @@ tnet_proxyinfo_t* tnet_proxydetect_get_info(const char* url, tnet_socket_type_t
}
// find best proxy
_appl_find_best_proxy(cfTargetUrl, cfProxies, &_info);
-
-
+
+
resolve_done:
if (cfUrl) {
CFRelease(cfUrl);
@@ -144,7 +143,7 @@ resolve_done:
if (cfProxies) {
CFRelease(cfProxies);
}
-
+
if (_appl_proxyinfo_is_valid(&_info)) {
info = tnet_proxyinfo_create();
if (info) {
@@ -157,7 +156,7 @@ resolve_done:
}
}
_appl_proxyinfo_release(&_info);
-
+
return info;
}
@@ -165,8 +164,8 @@ static tsk_bool_t _appl_proxyinfo_is_valid(const appl_proxyinfo_xt * info)
{
if (info) {
return info->port
- && info->type && !CFEqual(info->type, kCFProxyTypeNone)
- && info->host && CFStringGetLength(info->host) > 0 && CFStringCompare(info->host, CFSTR("127.0.0.1"), 0) != kCFCompareEqualTo;
+ && info->type && !CFEqual(info->type, kCFProxyTypeNone)
+ && info->host && CFStringGetLength(info->host) > 0 && CFStringCompare(info->host, CFSTR("127.0.0.1"), 0) != kCFCompareEqualTo;
}
return tsk_false;
}
@@ -201,7 +200,8 @@ static void _ProxyAutoConfigurationResultCallback(void *client, CFArrayRef proxy
CFTypeRef* cfResult = (CFTypeRef*)client;
if (error != NULL) {
*cfResult = CFRetain(error);
- } else {
+ }
+ else {
*cfResult = CFRetain(proxyList);
}
CFRunLoopStop(CFRunLoopGetCurrent());
@@ -212,14 +212,14 @@ static void _appl_find_best_proxy(CFURLRef cfTargetURL, CFArrayRef _cfProxies, a
CFDictionaryRef cfProxy;
CFIndex index = 0;
CFIndex count = CFArrayGetCount(_cfProxies);
-
+
while (index < count && (cfProxy = CFArrayGetValueAtIndex(_cfProxies, index++)) && !_appl_proxyinfo_is_valid(_proxyInfo)) {
_appl_proxyinfo_release(_proxyInfo);
CFStringRef cfProxyType = CFDictionaryGetValue(cfProxy, (const void*)kCFProxyTypeKey);
if (!cfProxyType) {
continue;
}
-
+
TSK_DEBUG_INFO("Found at %li proxy type = %s", (index - 1), CFStringGetCStringPtr(cfProxyType, kCFStringEncodingUTF8));
if (CFEqual(cfProxyType, kCFProxyTypeNone)) {
continue;
@@ -255,9 +255,9 @@ static void _appl_find_best_proxy(CFURLRef cfTargetURL, CFArrayRef _cfProxies, a
CFTypeRef cfResult = NULL;
CFStreamClientContext context = { 0, &cfResult, NULL, NULL, NULL };
CFRunLoopSourceRef cfrunLoop = CFNetworkExecuteProxyAutoConfigurationURL(cfPACUrl,
- cfTargetURL,
- _ProxyAutoConfigurationResultCallback,
- &context);
+ cfTargetURL,
+ _ProxyAutoConfigurationResultCallback,
+ &context);
if (!cfrunLoop) {
TSK_DEBUG_ERROR("CFNetworkExecuteProxyAutoConfigurationURL(%li, %s) failed", (index - 1), CFStringGetCStringPtr(CFURLGetString(cfPACUrl), kCFStringEncodingUTF8));
continue;
diff --git a/tinyNET/src/tnet_proxydetect.h b/tinyNET/src/tnet_proxydetect.h
index 23c5439..1f5597c 100755
--- a/tinyNET/src/tnet_proxydetect.h
+++ b/tinyNET/src/tnet_proxydetect.h
@@ -27,17 +27,17 @@
TNET_BEGIN_DECLS
typedef struct tnet_proxyinfo_s {
- TSK_DECLARE_OBJECT;
+ TSK_DECLARE_OBJECT;
- tnet_proxy_type_t type;
- char* autoconfig_url;
- tsk_bool_t autodetect;
- char* bypass_list;
+ tnet_proxy_type_t type;
+ char* autoconfig_url;
+ tsk_bool_t autodetect;
+ char* bypass_list;
char* hostname;
tnet_socket_type_t socket_type;
tnet_port_t port;
- char* username;
- char* password;
+ char* username;
+ char* password;
}
tnet_proxyinfo_t;
diff --git a/tinyNET/src/tnet_socket.c b/tinyNET/src/tnet_socket.c
index 2d104d1..5f071de 100755
--- a/tinyNET/src/tnet_socket.c
+++ b/tinyNET/src/tnet_socket.c
@@ -93,133 +93,133 @@ static int tnet_socket_close(tnet_socket_t *sock);
*/
tnet_socket_t* tnet_socket_create_2(const char* host, tnet_port_t port_, tnet_socket_type_t type, tsk_bool_t nonblocking, tsk_bool_t bindsocket)
{
- tnet_socket_t *sock;
- if ((sock = tsk_object_new(tnet_socket_def_t))) {
- int status;
- tsk_istr_t port;
- struct addrinfo *result = tsk_null;
- struct addrinfo *ptr = tsk_null;
- struct addrinfo hints;
- tnet_host_t local_hostname;
-
- sock->port = port_;
- tsk_itoa(sock->port, &port);
- sock->type = type;
-
- memset(local_hostname, 0, sizeof(local_hostname));
-
- /* Get the local host name */
- if (host != TNET_SOCKET_HOST_ANY && !tsk_strempty(host)){
- memcpy(local_hostname, host, tsk_strlen(host) > sizeof(local_hostname) - 1 ? sizeof(local_hostname) - 1 : tsk_strlen(host));
- }
- else{
- if (TNET_SOCKET_TYPE_IS_IPV6(sock->type)){
- memcpy(local_hostname, "::", 2);
- }
- else {
- memcpy(local_hostname, "0.0.0.0", 7);
- }
- }
-
- /* hints address info structure */
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = TNET_SOCKET_TYPE_IS_IPV46(sock->type) ? AF_UNSPEC : (TNET_SOCKET_TYPE_IS_IPV6(sock->type) ? AF_INET6 : AF_INET);
- hints.ai_socktype = TNET_SOCKET_TYPE_IS_STREAM(sock->type) ? SOCK_STREAM : SOCK_DGRAM;
- hints.ai_protocol = TNET_SOCKET_TYPE_IS_STREAM(sock->type) ? IPPROTO_TCP : IPPROTO_UDP;
- hints.ai_flags = AI_PASSIVE
+ tnet_socket_t *sock;
+ if ((sock = tsk_object_new(tnet_socket_def_t))) {
+ int status;
+ tsk_istr_t port;
+ struct addrinfo *result = tsk_null;
+ struct addrinfo *ptr = tsk_null;
+ struct addrinfo hints;
+ tnet_host_t local_hostname;
+
+ sock->port = port_;
+ tsk_itoa(sock->port, &port);
+ sock->type = type;
+
+ memset(local_hostname, 0, sizeof(local_hostname));
+
+ /* Get the local host name */
+ if (host != TNET_SOCKET_HOST_ANY && !tsk_strempty(host)) {
+ memcpy(local_hostname, host, tsk_strlen(host) > sizeof(local_hostname) - 1 ? sizeof(local_hostname) - 1 : tsk_strlen(host));
+ }
+ else {
+ if (TNET_SOCKET_TYPE_IS_IPV6(sock->type)) {
+ memcpy(local_hostname, "::", 2);
+ }
+ else {
+ memcpy(local_hostname, "0.0.0.0", 7);
+ }
+ }
+
+ /* hints address info structure */
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = TNET_SOCKET_TYPE_IS_IPV46(sock->type) ? AF_UNSPEC : (TNET_SOCKET_TYPE_IS_IPV6(sock->type) ? AF_INET6 : AF_INET);
+ hints.ai_socktype = TNET_SOCKET_TYPE_IS_STREAM(sock->type) ? SOCK_STREAM : SOCK_DGRAM;
+ hints.ai_protocol = TNET_SOCKET_TYPE_IS_STREAM(sock->type) ? IPPROTO_TCP : IPPROTO_UDP;
+ hints.ai_flags = AI_PASSIVE
#if !TNET_UNDER_WINDOWS || _WIN32_WINNT>=0x600
- | AI_ADDRCONFIG
+ | AI_ADDRCONFIG
#endif
- ;
-
- /* Performs getaddrinfo */
- if ((status = tnet_getaddrinfo(local_hostname, port, &hints, &result))) {
- TNET_PRINT_LAST_ERROR("tnet_getaddrinfo(family=%d, hostname=%s and port=%s) failed: [%s]",
- hints.ai_family, local_hostname, port, tnet_gai_strerror(status));
- goto bail;
- }
-
- /* Find our address. */
- for (ptr = result; ptr; ptr = ptr->ai_next){
- sock->fd = (tnet_fd_t)tnet_soccket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
- if (ptr->ai_family != AF_INET6 && ptr->ai_family != AF_INET){
- continue;
- }
- /* To avoid "Address already in use" error
- * Check issue 368 (https://code.google.com/p/doubango/issues/detail?id=368) to understand why it's not used for UDP/DTLS.
- */
- //
- if (TNET_SOCKET_TYPE_IS_STREAM(sock->type)) {
- if ((status = tnet_sockfd_reuseaddr(sock->fd, 1))) {
- // do not break...continue
- }
- }
-
- if (bindsocket){
- /* Bind the socket */
- if ((status = bind(sock->fd, ptr->ai_addr, (int)ptr->ai_addrlen))){
- TNET_PRINT_LAST_ERROR("bind to [%s:%s]have failed", local_hostname, port);
- tnet_socket_close(sock);
- continue;
- }
-
- /* Get local IP string. */
- if ((status = tnet_get_ip_n_port(sock->fd, tsk_true/*local*/, &sock->ip, &sock->port))) /* % */
- //if((status = tnet_getnameinfo(ptr->ai_addr, ptr->ai_addrlen, sock->ip, sizeof(sock->ip), 0, 0, NI_NUMERICHOST)))
- {
- TNET_PRINT_LAST_ERROR("Failed to get local IP and port.");
- tnet_socket_close(sock);
- continue;
- }
- }
-
- /* sets the real socket type (if ipv46) */
- if (ptr->ai_family == AF_INET6) {
- TNET_SOCKET_TYPE_SET_IPV6Only(sock->type);
- }
- else {
- TNET_SOCKET_TYPE_SET_IPV4Only(sock->type);
- }
- break;
- }
-
- /* Check socket validity. */
- if (!TNET_SOCKET_IS_VALID(sock)) {
- TNET_PRINT_LAST_ERROR("Invalid socket.");
- goto bail;
- }
+ ;
+
+ /* Performs getaddrinfo */
+ if ((status = tnet_getaddrinfo(local_hostname, port, &hints, &result))) {
+ TNET_PRINT_LAST_ERROR("tnet_getaddrinfo(family=%d, hostname=%s and port=%s) failed: [%s]",
+ hints.ai_family, local_hostname, port, tnet_gai_strerror(status));
+ goto bail;
+ }
+
+ /* Find our address. */
+ for (ptr = result; ptr; ptr = ptr->ai_next) {
+ sock->fd = (tnet_fd_t)tnet_soccket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
+ if (ptr->ai_family != AF_INET6 && ptr->ai_family != AF_INET) {
+ continue;
+ }
+ /* To avoid "Address already in use" error
+ * Check issue 368 (https://code.google.com/p/doubango/issues/detail?id=368) to understand why it's not used for UDP/DTLS.
+ */
+ //
+ if (TNET_SOCKET_TYPE_IS_STREAM(sock->type)) {
+ if ((status = tnet_sockfd_reuseaddr(sock->fd, 1))) {
+ // do not break...continue
+ }
+ }
+
+ if (bindsocket) {
+ /* Bind the socket */
+ if ((status = bind(sock->fd, ptr->ai_addr, (int)ptr->ai_addrlen))) {
+ TNET_PRINT_LAST_ERROR("bind to [%s:%s]have failed", local_hostname, port);
+ tnet_socket_close(sock);
+ continue;
+ }
+
+ /* Get local IP string. */
+ if ((status = tnet_get_ip_n_port(sock->fd, tsk_true/*local*/, &sock->ip, &sock->port))) /* % */
+ //if((status = tnet_getnameinfo(ptr->ai_addr, ptr->ai_addrlen, sock->ip, sizeof(sock->ip), 0, 0, NI_NUMERICHOST)))
+ {
+ TNET_PRINT_LAST_ERROR("Failed to get local IP and port.");
+ tnet_socket_close(sock);
+ continue;
+ }
+ }
+
+ /* sets the real socket type (if ipv46) */
+ if (ptr->ai_family == AF_INET6) {
+ TNET_SOCKET_TYPE_SET_IPV6Only(sock->type);
+ }
+ else {
+ TNET_SOCKET_TYPE_SET_IPV4Only(sock->type);
+ }
+ break;
+ }
+
+ /* Check socket validity. */
+ if (!TNET_SOCKET_IS_VALID(sock)) {
+ TNET_PRINT_LAST_ERROR("Invalid socket.");
+ goto bail;
+ }
#if TNET_UNDER_IPHONE || TNET_UNDER_IPHONE_SIMULATOR
- /* disable SIGPIPE signal */
- {
- int yes = 1;
- if (setsockopt(sock->fd, SOL_SOCKET, SO_NOSIGPIPE, (char*)&yes, sizeof(int))){
- TNET_PRINT_LAST_ERROR("setsockopt(SO_NOSIGPIPE) have failed.");
- }
- }
+ /* disable SIGPIPE signal */
+ {
+ int yes = 1;
+ if (setsockopt(sock->fd, SOL_SOCKET, SO_NOSIGPIPE, (char*)&yes, sizeof(int))) {
+ TNET_PRINT_LAST_ERROR("setsockopt(SO_NOSIGPIPE) have failed.");
+ }
+ }
#endif /* TNET_UNDER_IPHONE */
- /* Sets the socket to nonblocking mode */
- if(nonblocking){
- if((status = tnet_sockfd_set_nonblocking(sock->fd))){
- goto bail;
- }
- }
-
- bail:
- /* Free addrinfo */
- tnet_freeaddrinfo(result);
-
- /* Close socket if failed. */
- if (status){
- if (TNET_SOCKET_IS_VALID(sock)){
- tnet_socket_close(sock);
- }
- return tsk_null;
- }
-}
+ /* Sets the socket to nonblocking mode */
+ if(nonblocking) {
+ if((status = tnet_sockfd_set_nonblocking(sock->fd))) {
+ goto bail;
+ }
+ }
+
+bail:
+ /* Free addrinfo */
+ tnet_freeaddrinfo(result);
- return sock;
+ /* Close socket if failed. */
+ if (status) {
+ if (TNET_SOCKET_IS_VALID(sock)) {
+ tnet_socket_close(sock);
+ }
+ return tsk_null;
+ }
+ }
+
+ return sock;
}
/**@ingroup tnet_socket_group
@@ -232,7 +232,7 @@ tnet_socket_t* tnet_socket_create_2(const char* host, tnet_port_t port_, tnet_so
*/
tnet_socket_t* tnet_socket_create(const char* host, tnet_port_t port, tnet_socket_type_t type)
{
- return tnet_socket_create_2(host, port, type, tsk_true, tsk_true);
+ return tnet_socket_create_2(host, port, type, tsk_true, tsk_true);
}
/**@ingroup tnet_socket_group
@@ -240,15 +240,15 @@ tnet_socket_t* tnet_socket_create(const char* host, tnet_port_t port, tnet_socke
*/
int tnet_socket_send_stream(tnet_socket_t* self, const void* data, tsk_size_t size)
{
- if (!self || self->fd == TNET_INVALID_FD || !data || !size || !TNET_SOCKET_TYPE_IS_STREAM(self->type)) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (self->tlshandle && (TNET_SOCKET_TYPE_IS_TLS(self->type) || TNET_SOCKET_TYPE_IS_WSS(self->type))) {
- return tnet_tls_socket_send(self->tlshandle, data, size) == 0 ? (int)size : -1; // returns zero on success
- }
-
- return (int)tnet_sockfd_send(self->fd, data, size, 0);
+ if (!self || self->fd == TNET_INVALID_FD || !data || !size || !TNET_SOCKET_TYPE_IS_STREAM(self->type)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (self->tlshandle && (TNET_SOCKET_TYPE_IS_TLS(self->type) || TNET_SOCKET_TYPE_IS_WSS(self->type))) {
+ return tnet_tls_socket_send(self->tlshandle, data, size) == 0 ? (int)size : -1; // returns zero on success
+ }
+
+ return (int)tnet_sockfd_send(self->fd, data, size, 0);
}
/**@ingroup tnet_socket_group
@@ -264,7 +264,7 @@ int tnet_socket_handle_brokenpipe(tnet_socket_t* self)
}
fd_old = self->fd;
fd_new = TNET_INVALID_FD;
-
+
// close old fd
ret = tnet_sockfd_close(&self->fd);
// try to create an fd binding to the same address
@@ -277,7 +277,7 @@ int tnet_socket_handle_brokenpipe(tnet_socket_t* self)
/* disable SIGPIPE signal */
{
int yes = 1;
- if (setsockopt(fd_new, SOL_SOCKET, SO_NOSIGPIPE, (char*)&yes, sizeof(int))){
+ if (setsockopt(fd_new, SOL_SOCKET, SO_NOSIGPIPE, (char*)&yes, sizeof(int))) {
TNET_PRINT_LAST_ERROR("setsockopt(%d, SO_NOSIGPIPE) have failed", fd_new);
}
}
@@ -294,7 +294,7 @@ int tnet_socket_handle_brokenpipe(tnet_socket_t* self)
**/
static int tnet_socket_close(tnet_socket_t *sock)
{
- return tnet_sockfd_close(&(sock->fd));
+ return tnet_sockfd_close(&(sock->fd));
}
//=================================================================================================
@@ -302,37 +302,36 @@ static int tnet_socket_close(tnet_socket_t *sock)
//
static tsk_object_t* tnet_socket_ctor(tsk_object_t * self, va_list * app)
{
- tnet_socket_t *sock = self;
- if (sock){
- }
- return self;
+ tnet_socket_t *sock = self;
+ if (sock) {
+ }
+ return self;
}
static tsk_object_t* tnet_socket_dtor(tsk_object_t * self)
{
- tnet_socket_t *sock = self;
+ tnet_socket_t *sock = self;
- if (sock){
- /* Close the socket */
- if (TNET_SOCKET_IS_VALID(sock)){
- tnet_socket_close(sock);
- }
- /* Clean up TLS handle */
- TSK_OBJECT_SAFE_FREE(sock->tlshandle);
+ if (sock) {
+ /* Close the socket */
+ if (TNET_SOCKET_IS_VALID(sock)) {
+ tnet_socket_close(sock);
+ }
+ /* Clean up TLS handle */
+ TSK_OBJECT_SAFE_FREE(sock->tlshandle);
- /* Clean up DTLS handle */
- TSK_OBJECT_SAFE_FREE(sock->dtlshandle);
- }
+ /* Clean up DTLS handle */
+ TSK_OBJECT_SAFE_FREE(sock->dtlshandle);
+ }
- return self;
+ return self;
}
-static const tsk_object_def_t tnet_socket_def_s =
-{
- sizeof(tnet_socket_t),
- tnet_socket_ctor,
- tnet_socket_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_socket_def_s = {
+ sizeof(tnet_socket_t),
+ tnet_socket_ctor,
+ tnet_socket_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_socket_def_t = &tnet_socket_def_s;
diff --git a/tinyNET/src/tnet_socket.h b/tinyNET/src/tnet_socket.h
index 3c7dc34..daceb53 100755
--- a/tinyNET/src/tnet_socket.h
+++ b/tinyNET/src/tnet_socket.h
@@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -38,9 +38,8 @@
TNET_BEGIN_DECLS
-typedef enum tnet_socket_type_e
-{
- tnet_socket_type_invalid = 0x0000, /**< Invalid socket.*/
+typedef enum tnet_socket_type_e {
+ tnet_socket_type_invalid = 0x0000, /**< Invalid socket.*/
#define TNET_SOCKET_TYPE_IPV4 (0x0001 << 0)
#define TNET_SOCKET_TYPE_UDP (0x0001 << 1)
@@ -50,53 +49,53 @@ typedef enum tnet_socket_type_e
#define TNET_SOCKET_TYPE_SCTP (0x0001 << 5)
#define TNET_SOCKET_TYPE_WS (0x0001 << 6)
#define TNET_SOCKET_TYPE_WSS (0x0001 << 7)
- tnet_socket_type_udp_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_UDP), /**< UDP/IPv4 socket.*/
- tnet_socket_type_dtls_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_DTLS), /**< DTLS/IPv4 socket.*/
- tnet_socket_type_tcp_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_TCP), /**< TCP/IPv4 socket.*/
- tnet_socket_type_tls_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_TLS), /**< TLS/IPv4 socket.*/
- tnet_socket_type_sctp_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_SCTP), /**< SCTP/IPv4 socket.*/
- tnet_socket_type_ws_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_WS), /**< WebSocket/IPv4 socket.*/
- tnet_socket_type_wss_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_WSS), /**< WebSocket Secure/IPv4 socket.*/
+ tnet_socket_type_udp_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_UDP), /**< UDP/IPv4 socket.*/
+ tnet_socket_type_dtls_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_DTLS), /**< DTLS/IPv4 socket.*/
+ tnet_socket_type_tcp_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_TCP), /**< TCP/IPv4 socket.*/
+ tnet_socket_type_tls_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_TLS), /**< TLS/IPv4 socket.*/
+ tnet_socket_type_sctp_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_SCTP), /**< SCTP/IPv4 socket.*/
+ tnet_socket_type_ws_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_WS), /**< WebSocket/IPv4 socket.*/
+ tnet_socket_type_wss_ipv4 = (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_WSS), /**< WebSocket Secure/IPv4 socket.*/
#define TNET_SOCKET_TYPE_IPSEC (0x0001 << 8)
- tnet_socket_type_udp_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_udp_ipv4), /**< UDP/IPSec/IPv4 socket.*/
- tnet_socket_type_dtls_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_dtls_ipv4), /**< DTLS/IPSec/IPv4 socket.*/
- tnet_socket_type_tcp_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tcp_ipv4), /**< TCP/IPSec/IPv4 socket.*/
- tnet_socket_type_tls_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tls_ipv4), /**< TLS/IPSec /IPv4socket.*/
- tnet_socket_type_sctp_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_sctp_ipv4), /**< SCTP/IPSec/IPv4 socket.*/
- tnet_socket_type_ws_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_ws_ipv4), /**< WS/IPSec/IPv4 socket.*/
- tnet_socket_type_wss_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_wss_ipv4), /**< WSS/IPSec/IPv4 socket.*/
+ tnet_socket_type_udp_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_udp_ipv4), /**< UDP/IPSec/IPv4 socket.*/
+ tnet_socket_type_dtls_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_dtls_ipv4), /**< DTLS/IPSec/IPv4 socket.*/
+ tnet_socket_type_tcp_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tcp_ipv4), /**< TCP/IPSec/IPv4 socket.*/
+ tnet_socket_type_tls_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tls_ipv4), /**< TLS/IPSec /IPv4socket.*/
+ tnet_socket_type_sctp_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_sctp_ipv4), /**< SCTP/IPSec/IPv4 socket.*/
+ tnet_socket_type_ws_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_ws_ipv4), /**< WS/IPSec/IPv4 socket.*/
+ tnet_socket_type_wss_ipsec_ipv4 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_wss_ipv4), /**< WSS/IPSec/IPv4 socket.*/
#define TNET_SOCKET_TYPE_IPV6 (0x0001 << 12)
- tnet_socket_type_udp_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_udp_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< UDP/IPv6 socket.*/
- tnet_socket_type_dtls_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_dtls_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< DTLS/IPv6 socket.*/
- tnet_socket_type_tcp_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_tcp_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< TCP/IPv6 socket.*/
- tnet_socket_type_tls_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_tls_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< TLS/IPv6 socket.*/
- tnet_socket_type_sctp_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_sctp_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< SCTP/IPv6 socket.*/
- tnet_socket_type_ws_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_ws_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< WS/IPv6 socket.*/
- tnet_socket_type_wss_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_wss_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< WSS/IPv6 socket.*/
- tnet_socket_type_udp_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_udp_ipv6), /**< UDP/IPSec/IPv6 socket.*/
- tnet_socket_type_tcp_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tcp_ipv6), /**< TCP/IPSec/IPv6 socket.*/
- tnet_socket_type_tls_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tls_ipv6), /**< TLS/IPSec/IPv6 socket.*/
- tnet_socket_type_sctp_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_sctp_ipv6),/**< SCTP/IPSec/IPv6 socket.*/
- tnet_socket_type_ws_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_ws_ipv6), /**< WS/IPSec/IPv6 socket.*/
- tnet_socket_type_wss_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_wss_ipv6),/**< WSS/IPSec/IPv6 socket.*/
+ tnet_socket_type_udp_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_udp_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< UDP/IPv6 socket.*/
+ tnet_socket_type_dtls_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_dtls_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< DTLS/IPv6 socket.*/
+ tnet_socket_type_tcp_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_tcp_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< TCP/IPv6 socket.*/
+ tnet_socket_type_tls_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_tls_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< TLS/IPv6 socket.*/
+ tnet_socket_type_sctp_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_sctp_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< SCTP/IPv6 socket.*/
+ tnet_socket_type_ws_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_ws_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< WS/IPv6 socket.*/
+ tnet_socket_type_wss_ipv6 = (TNET_SOCKET_TYPE_IPV6 | (tnet_socket_type_wss_ipv4 ^ TNET_SOCKET_TYPE_IPV4)), /**< WSS/IPv6 socket.*/
+ tnet_socket_type_udp_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_udp_ipv6), /**< UDP/IPSec/IPv6 socket.*/
+ tnet_socket_type_tcp_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tcp_ipv6), /**< TCP/IPSec/IPv6 socket.*/
+ tnet_socket_type_tls_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tls_ipv6), /**< TLS/IPSec/IPv6 socket.*/
+ tnet_socket_type_sctp_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_sctp_ipv6),/**< SCTP/IPSec/IPv6 socket.*/
+ tnet_socket_type_ws_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_ws_ipv6), /**< WS/IPSec/IPv6 socket.*/
+ tnet_socket_type_wss_ipsec_ipv6 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_wss_ipv6),/**< WSS/IPSec/IPv6 socket.*/
#define TNET_SOCKET_TYPE_IPV46 (TNET_SOCKET_TYPE_IPV4 | TNET_SOCKET_TYPE_IPV6)
- tnet_socket_type_udp_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_udp_ipv4 | tnet_socket_type_udp_ipv6)), /**< UDP/IPv4/6 socket.*/
- tnet_socket_type_dtls_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_dtls_ipv4 | tnet_socket_type_dtls_ipv6)), /**< DTLS/IPv4/6 socket.*/
- tnet_socket_type_tcp_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_tcp_ipv4 | tnet_socket_type_tcp_ipv6)), /**< TCP/IPv4/6 socket.*/
- tnet_socket_type_tls_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_tls_ipv4 | tnet_socket_type_tls_ipv6)), /**< TLS/IPv4/6 socket.*/
- tnet_socket_type_sctp_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_sctp_ipv4 | tnet_socket_type_sctp_ipv6)), /**< SCTP/IPv4/6 socket.*/
- tnet_socket_type_ws_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_ws_ipv4 | tnet_socket_type_ws_ipv6)), /**< WS/IPv4/6 socket.*/
- tnet_socket_type_wss_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_wss_ipv4 | tnet_socket_type_wss_ipv6)), /**< WSS/IPv4/6 socket.*/
- tnet_socket_type_udp_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_udp_ipv46), /**< UDP/IPSec/IPv4/6 socket.*/
- tnet_socket_type_dtls_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_dtls_ipv46), /**< DTLS/IPSec/IPv4/6 socket.*/
- tnet_socket_type_tcp_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tcp_ipv46), /**< TCP/IPSec/IPv4/6 socket.*/
- tnet_socket_type_tls_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tls_ipv46), /**< TLS/IPSec/IPv4/6 socket.*/
- tnet_socket_type_sctp_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_sctp_ipv46),/**< SCTP/IPSec/IPv4/6 socket.*/
- tnet_socket_type_ws_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_ws_ipv46),/**< WS/IPSec/IPv4/6 socket.*/
- tnet_socket_type_wss_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_wss_ipv46),/**< WSS/IPSec/IPv4/6 socket.*/
+ tnet_socket_type_udp_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_udp_ipv4 | tnet_socket_type_udp_ipv6)), /**< UDP/IPv4/6 socket.*/
+ tnet_socket_type_dtls_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_dtls_ipv4 | tnet_socket_type_dtls_ipv6)), /**< DTLS/IPv4/6 socket.*/
+ tnet_socket_type_tcp_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_tcp_ipv4 | tnet_socket_type_tcp_ipv6)), /**< TCP/IPv4/6 socket.*/
+ tnet_socket_type_tls_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_tls_ipv4 | tnet_socket_type_tls_ipv6)), /**< TLS/IPv4/6 socket.*/
+ tnet_socket_type_sctp_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_sctp_ipv4 | tnet_socket_type_sctp_ipv6)), /**< SCTP/IPv4/6 socket.*/
+ tnet_socket_type_ws_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_ws_ipv4 | tnet_socket_type_ws_ipv6)), /**< WS/IPv4/6 socket.*/
+ tnet_socket_type_wss_ipv46 = (TNET_SOCKET_TYPE_IPV46 | (tnet_socket_type_wss_ipv4 | tnet_socket_type_wss_ipv6)), /**< WSS/IPv4/6 socket.*/
+ tnet_socket_type_udp_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_udp_ipv46), /**< UDP/IPSec/IPv4/6 socket.*/
+ tnet_socket_type_dtls_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_dtls_ipv46), /**< DTLS/IPSec/IPv4/6 socket.*/
+ tnet_socket_type_tcp_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tcp_ipv46), /**< TCP/IPSec/IPv4/6 socket.*/
+ tnet_socket_type_tls_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_tls_ipv46), /**< TLS/IPSec/IPv4/6 socket.*/
+ tnet_socket_type_sctp_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_sctp_ipv46),/**< SCTP/IPSec/IPv4/6 socket.*/
+ tnet_socket_type_ws_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_ws_ipv46),/**< WS/IPSec/IPv4/6 socket.*/
+ tnet_socket_type_wss_ipsec_ipv46 = (TNET_SOCKET_TYPE_IPSEC | tnet_socket_type_wss_ipv46),/**< WSS/IPSec/IPv4/6 socket.*/
}
tnet_socket_type_t;
@@ -165,17 +164,16 @@ tnet_socket_type_t;
/**
* Socket.
*/
-typedef struct tnet_socket_s
-{
- TSK_DECLARE_OBJECT;
-
- tnet_socket_type_t type;
- tnet_fd_t fd;
- tnet_ip_t ip;
- uint16_t port;
-
- tnet_tls_socket_handle_t* tlshandle;
- tnet_dtls_socket_handle_t* dtlshandle;
+typedef struct tnet_socket_s {
+ TSK_DECLARE_OBJECT;
+
+ tnet_socket_type_t type;
+ tnet_fd_t fd;
+ tnet_ip_t ip;
+ uint16_t port;
+
+ tnet_tls_socket_handle_t* tlshandle;
+ tnet_dtls_socket_handle_t* dtlshandle;
}
tnet_socket_t;
diff --git a/tinyNET/src/tnet_transport.c b/tinyNET/src/tnet_transport.c
index 7d26d08..fe9810e 100755
--- a/tinyNET/src/tnet_transport.c
+++ b/tinyNET/src/tnet_transport.c
@@ -56,7 +56,7 @@ static int _tnet_transport_dtls_cb(const void* usrdata, tnet_dtls_socket_event_t
static int _tnet_transport_ssl_init(tnet_transport_t* transport)
{
- if (!transport){
+ if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -65,20 +65,20 @@ static int _tnet_transport_ssl_init(tnet_transport_t* transport)
tnet_socket_type_t type = tnet_transport_get_type(transport);
tsk_bool_t is_tls = (TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type));
tsk_bool_t is_dtls = transport->dtls.enabled/* TNET_SOCKET_TYPE_IS_DTLS(type)*/; // DTLS-RTP, not raw DTLS
- if (is_dtls && !tnet_dtls_is_supported()){
+ if (is_dtls && !tnet_dtls_is_supported()) {
TSK_DEBUG_ERROR("Requesting to create DTLS transport but source code not built with support for this feature");
return -1;
}
- if (is_tls && !tnet_tls_is_supported()){
+ if (is_tls && !tnet_tls_is_supported()) {
TSK_DEBUG_ERROR("Requesting to create TLS transport but source code not built with support for this feature");
return -1;
}
- if ((transport->tls.enabled = is_tls)){
- if (!transport->tls.ctx_client && !(transport->tls.ctx_client = SSL_CTX_new(SSLv23_client_method()))){
+ if ((transport->tls.enabled = is_tls)) {
+ if (!transport->tls.ctx_client && !(transport->tls.ctx_client = SSL_CTX_new(SSLv23_client_method()))) {
TSK_DEBUG_ERROR("Failed to create SSL client context");
return -2;
}
- if (!transport->tls.ctx_server && !(transport->tls.ctx_server = SSL_CTX_new(SSLv23_server_method()))){
+ if (!transport->tls.ctx_server && !(transport->tls.ctx_server = SSL_CTX_new(SSLv23_server_method()))) {
TSK_DEBUG_ERROR("Failed to create SSL server context");
return -3;
}
@@ -86,56 +86,56 @@ static int _tnet_transport_ssl_init(tnet_transport_t* transport)
SSL_CTX_set_mode(transport->tls.ctx_server, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_verify(transport->tls.ctx_server, SSL_VERIFY_NONE, tsk_null); // to be updated by tnet_transport_tls_set_certs()
SSL_CTX_set_verify(transport->tls.ctx_client, SSL_VERIFY_NONE, tsk_null); // to be updated by tnet_transport_tls_set_certs()
- if (SSL_CTX_set_cipher_list(transport->tls.ctx_client, TNET_CIPHER_LIST) <= 0 || SSL_CTX_set_cipher_list(transport->tls.ctx_server, TNET_CIPHER_LIST) <= 0){
+ if (SSL_CTX_set_cipher_list(transport->tls.ctx_client, TNET_CIPHER_LIST) <= 0 || SSL_CTX_set_cipher_list(transport->tls.ctx_server, TNET_CIPHER_LIST) <= 0) {
TSK_DEBUG_ERROR("SSL_CTX_set_cipher_list failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
return -4;
}
}
#if HAVE_OPENSSL_DTLS
- if ((transport->dtls.enabled = is_dtls)){
- if (!transport->dtls.ctx && !(transport->dtls.ctx = SSL_CTX_new(DTLSv1_method()))){
- TSK_DEBUG_ERROR("Failed to create DTLSv1 context");
- TSK_OBJECT_SAFE_FREE(transport);
- return -5;
- }
- SSL_CTX_set_read_ahead(transport->dtls.ctx, 1);
- // SSL_CTX_set_options(transport->dtls.ctx, SSL_OP_ALL);
- // SSL_CTX_set_mode(transport->dtls.ctx, SSL_MODE_AUTO_RETRY);
- SSL_CTX_set_verify(transport->dtls.ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, tsk_null); // to be updated by tnet_transport_tls_set_certs()
- if (SSL_CTX_set_cipher_list(transport->dtls.ctx, TNET_CIPHER_LIST) <= 0){
- TSK_DEBUG_ERROR("SSL_CTX_set_cipher_list failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
- return -6;
- }
- //!\ This is required even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
- // Up to the DTLS socket to set the default MTU value
- SSL_CTX_set_options(transport->dtls.ctx, SSL_OP_NO_QUERY_MTU);
- SSL_CTX_ctrl(transport->dtls.ctx, SSL_CTRL_SET_MTU, TNET_DTLS_MTU - 28, NULL);
-
- transport->dtls.activated = tsk_true;
- }
+ if ((transport->dtls.enabled = is_dtls)) {
+ if (!transport->dtls.ctx && !(transport->dtls.ctx = SSL_CTX_new(DTLSv1_method()))) {
+ TSK_DEBUG_ERROR("Failed to create DTLSv1 context");
+ TSK_OBJECT_SAFE_FREE(transport);
+ return -5;
+ }
+ SSL_CTX_set_read_ahead(transport->dtls.ctx, 1);
+ // SSL_CTX_set_options(transport->dtls.ctx, SSL_OP_ALL);
+ // SSL_CTX_set_mode(transport->dtls.ctx, SSL_MODE_AUTO_RETRY);
+ SSL_CTX_set_verify(transport->dtls.ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, tsk_null); // to be updated by tnet_transport_tls_set_certs()
+ if (SSL_CTX_set_cipher_list(transport->dtls.ctx, TNET_CIPHER_LIST) <= 0) {
+ TSK_DEBUG_ERROR("SSL_CTX_set_cipher_list failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
+ return -6;
+ }
+ //!\ This is required even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
+ // Up to the DTLS socket to set the default MTU value
+ SSL_CTX_set_options(transport->dtls.ctx, SSL_OP_NO_QUERY_MTU);
+ SSL_CTX_ctrl(transport->dtls.ctx, SSL_CTRL_SET_MTU, TNET_DTLS_MTU - 28, NULL);
+
+ transport->dtls.activated = tsk_true;
+ }
#endif /* HAVE_OPENSSL_DTLS */
}
#endif /* HAVE_OPENSSL */
-
+
return 0;
}
static int _tnet_transport_ssl_deinit(tnet_transport_t* transport)
{
- if (!transport){
+ if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
#if HAVE_OPENSSL
- if (transport->tls.ctx_client){
+ if (transport->tls.ctx_client) {
SSL_CTX_free(transport->tls.ctx_client);
transport->tls.ctx_client = tsk_null;
}
- if (transport->tls.ctx_server){
+ if (transport->tls.ctx_server) {
SSL_CTX_free(transport->tls.ctx_server);
transport->tls.ctx_server = tsk_null;
}
- if (transport->dtls.ctx){
+ if (transport->dtls.ctx) {
SSL_CTX_free(transport->dtls.ctx);
transport->dtls.ctx = tsk_null;
}
@@ -146,63 +146,63 @@ static int _tnet_transport_ssl_deinit(tnet_transport_t* transport)
tnet_transport_t* tnet_transport_create(const char* host, tnet_port_t port, tnet_socket_type_t type, const char* description)
{
tnet_transport_t* transport;
-
- if ((transport = tsk_object_new(tnet_transport_def_t))){
+
+ if ((transport = tsk_object_new(tnet_transport_def_t))) {
transport->description = tsk_strdup(description);
transport->local_host = tsk_strdup(host);
transport->req_local_port = port;
transport->type = type;
transport->context = tnet_transport_context_create();
-
- if ((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))){
+
+ if ((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))) {
transport->local_ip = tsk_strdup(transport->master->ip);
transport->bind_local_port = transport->master->port;
}
- else{
+ else {
TSK_DEBUG_ERROR("Failed to create master socket");
TSK_OBJECT_SAFE_FREE(transport);
}
-
- if (_tnet_transport_ssl_init(transport) != 0){
+
+ if (_tnet_transport_ssl_init(transport) != 0) {
TSK_DEBUG_ERROR("Failed to initialize TLS and/or DTLS caps");
TSK_OBJECT_SAFE_FREE(transport);
}
// set priority
tsk_runnable_set_priority(TSK_RUNNABLE(transport), TSK_THREAD_PRIORITY_TIME_CRITICAL);
}
-
+
return transport;
}
tnet_transport_t* tnet_transport_create_2(tnet_socket_t *master, const char* description)
{
tnet_transport_t* transport;
- if (!master){
+ if (!master) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
- if ((transport = tsk_object_new(tnet_transport_def_t))){
+
+ if ((transport = tsk_object_new(tnet_transport_def_t))) {
transport->description = tsk_strdup(description);
transport->local_host = tsk_strdup(master->ip);
transport->req_local_port = master->port;
transport->type = master->type;
-
+
transport->master = tsk_object_ref(master);
transport->local_ip = tsk_strdup(transport->master->ip);
transport->bind_local_port = transport->master->port;
-
+
transport->context = tnet_transport_context_create();
-
- if (_tnet_transport_ssl_init(transport) != 0){
+
+ if (_tnet_transport_ssl_init(transport) != 0) {
TSK_DEBUG_ERROR("Failed to initialize TLS and/or DTLS caps");
TSK_OBJECT_SAFE_FREE(transport);
}
-
+
// set priority
tsk_runnable_set_priority(TSK_RUNNABLE(transport), TSK_THREAD_PRIORITY_TIME_CRITICAL);
}
-
+
return transport;
}
@@ -215,53 +215,53 @@ int tnet_transport_tls_set_certs(tnet_transport_handle_t *handle, const char* ca
{
tnet_transport_t *transport = handle;
static const char* ssl_password = tsk_null;
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
tsk_strupdate(&transport->tls.ca, ca);
tsk_strupdate(&transport->tls.pvk, pvk);
tsk_strupdate(&transport->tls.pbk, pbk);
transport->tls.verify = verify;
-
+
#if HAVE_OPENSSL
{
int32_t i, ret;
SSL_CTX* contexts[3] = { tsk_null };
-
+
/* init DTLS/TLS contexts */
- if ((ret = _tnet_transport_ssl_init(transport))){
+ if ((ret = _tnet_transport_ssl_init(transport))) {
return ret;
}
-
- if (transport->tls.enabled){
+
+ if (transport->tls.enabled) {
contexts[0] = transport->tls.ctx_client;
contexts[1] = transport->tls.ctx_server;
}
- if (transport->dtls.enabled){
+ if (transport->dtls.enabled) {
contexts[2] = transport->dtls.ctx;
/* Reset fingerprints */
memset(transport->dtls.fingerprints, 0, sizeof(transport->dtls.fingerprints));
}
-
- for (i = 0; i < sizeof(contexts) / sizeof(contexts[0]); ++i){
- if (!contexts[i]){
+
+ for (i = 0; i < sizeof(contexts) / sizeof(contexts[0]); ++i) {
+ if (!contexts[i]) {
continue;
}
SSL_CTX_set_verify(contexts[i], transport->tls.verify ? (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT) : SSL_VERIFY_NONE, tsk_null);
- if (!tsk_strnullORempty(transport->tls.pbk) || !tsk_strnullORempty(transport->tls.pvk) || !tsk_strnullORempty(transport->tls.ca)){
+ if (!tsk_strnullORempty(transport->tls.pbk) || !tsk_strnullORempty(transport->tls.pvk) || !tsk_strnullORempty(transport->tls.ca)) {
/* Sets Public key (cert) */
if (!tsk_strnullORempty(transport->tls.pbk) && (ret = SSL_CTX_use_certificate_file(contexts[i], transport->tls.pbk, SSL_FILETYPE_PEM)) != 1) {
TSK_DEBUG_ERROR("SSL_CTX_use_certificate_file failed [%d,%s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
return -3;
}
/*Sets the password of the private key*/
- if (!tsk_strnullORempty(ssl_password)){
+ if (!tsk_strnullORempty(ssl_password)) {
SSL_CTX_set_default_passwd_cb_userdata(contexts[i], (void*)ssl_password);
}
-
+
/* Sets Private key (cert) */
if (!tsk_strnullORempty(transport->tls.pvk) && (ret = SSL_CTX_use_PrivateKey_file(contexts[i], transport->tls.pvk, SSL_FILETYPE_PEM)) != 1) {
TSK_DEBUG_ERROR("SSL_CTX_use_PrivateKey_file failed [%d,%s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
@@ -281,47 +281,46 @@ int tnet_transport_tls_set_certs(tnet_transport_handle_t *handle, const char* ca
}
}
#endif /* HAVE_OPENSSL */
-
+
return 0;
}
int tnet_transport_start(tnet_transport_handle_t* handle)
{
int ret = -1;
- if (handle){
+ if (handle) {
tnet_transport_t *transport = handle;
-
+
/* prepare transport */
- if ((ret = tnet_transport_prepare(transport))){
+ if ((ret = tnet_transport_prepare(transport))) {
TSK_DEBUG_ERROR("Failed to prepare transport.");
goto bail;
}
-
+
/* start transport */
TSK_RUNNABLE(transport)->run = run;
- if ((ret = tsk_runnable_start(TSK_RUNNABLE(transport), tnet_transport_event_def_t))){
+ if ((ret = tsk_runnable_start(TSK_RUNNABLE(transport), tnet_transport_event_def_t))) {
TSK_DEBUG_ERROR("Failed to start transport.");
goto bail;
}
}
- else{
+ else {
TSK_DEBUG_ERROR("NULL transport object.");
}
-
+
bail:
return ret;
}
int tnet_transport_issecure(const tnet_transport_handle_t *handle)
{
- if (handle)
- {
+ if (handle) {
const tnet_transport_t *transport = handle;
- if (transport->master){
+ if (transport->master) {
return TNET_SOCKET_TYPE_IS_SECURE(transport->master->type);
}
}
- else{
+ else {
TSK_DEBUG_ERROR("NULL transport object.");
}
return 0;
@@ -329,11 +328,11 @@ int tnet_transport_issecure(const tnet_transport_handle_t *handle)
const char* tnet_transport_get_description(const tnet_transport_handle_t *handle)
{
- if (handle){
+ if (handle) {
const tnet_transport_t *transport = handle;
return transport->description;
}
- else{
+ else {
TSK_DEBUG_ERROR("NULL transport object.");
return tsk_null;
}
@@ -341,10 +340,10 @@ const char* tnet_transport_get_description(const tnet_transport_handle_t *handle
int tnet_transport_get_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_ip_t *ip, tnet_port_t *port)
{
- if (handle){
+ if (handle) {
return tnet_get_ip_n_port(fd, tsk_true/*local*/, ip, port);
}
- else{
+ else {
TSK_DEBUG_ERROR("NULL transport object.");
}
return -1;
@@ -353,17 +352,17 @@ int tnet_transport_get_ip_n_port(const tnet_transport_handle_t *handle, tnet_fd_
int tnet_transport_get_ip_n_port_2(const tnet_transport_handle_t *handle, tnet_ip_t *ip, tnet_port_t *port)
{
const tnet_transport_t *transport = handle;
- if (transport){
+ if (transport) {
// do not check the master, let the application die if "null"
- if (ip){
+ if (ip) {
memcpy(*ip, transport->master->ip, sizeof(transport->master->ip));
}
- if (port){
+ if (port) {
*port = transport->master->port;
}
return 0;
}
- else{
+ else {
TSK_DEBUG_ERROR("NULL transport object.");
return -1;
}
@@ -385,27 +384,27 @@ int tnet_transport_get_public_ip_n_port(const tnet_transport_handle_t *handle, t
tsk_bool_t stun_ok = tsk_false;
struct tnet_nat_ctx_s* natt_ctx;
const tnet_transport_t *transport = handle;
- if (!transport){
+ if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
if (TNET_SOCKET_TYPE_IS_DGRAM(transport->type) && (natt_ctx = tsk_object_ref(transport->natt_ctx))) {
tnet_stun_binding_id_t bind_id = kStunBindingInvalidId;
// if the socket is already monitored by the transport we should pause because both the transport and
// NAT binder will try to read from it
-
+
// Pause the soket
tnet_transport_pause_socket(transport, fd, tsk_true);
// Performs STUN binding
bind_id = tnet_nat_stun_bind(transport->natt_ctx, fd);
// Resume the socket
tnet_transport_pause_socket(transport, fd, tsk_false);
-
+
if (bind_id != kStunBindingInvalidId) {
char* public_ip = tsk_null;
- if (tnet_nat_stun_get_reflexive_address(transport->natt_ctx, bind_id, &public_ip, port) == 0){
- if (ip && public_ip){
+ if (tnet_nat_stun_get_reflexive_address(transport->natt_ctx, bind_id, &public_ip, port) == 0) {
+ if (ip && public_ip) {
tsk_size_t ip_len = tsk_strlen(public_ip);
memcpy(ip, public_ip, ip_len > sizeof(*ip) ? sizeof(*ip) : ip_len);
}
@@ -416,44 +415,44 @@ int tnet_transport_get_public_ip_n_port(const tnet_transport_handle_t *handle, t
}
tsk_object_unref(natt_ctx);
}
-
- if (!stun_ok){
- if (fd == TNET_INVALID_FD && transport->local_ip){
+
+ if (!stun_ok) {
+ if (fd == TNET_INVALID_FD && transport->local_ip) {
memcpy(*ip, transport->local_ip, TSK_MIN(sizeof(tnet_ip_t), tsk_strlen(transport->local_ip)));
*port = transport->bind_local_port;
return 0;
}
- else{
+ else {
return tnet_transport_get_ip_n_port(handle, fd, ip, port);
}
}
-
+
return 0;
}
const char* tnet_transport_dtls_get_local_fingerprint(const tnet_transport_handle_t *handle, tnet_dtls_hash_type_t hash)
{
const tnet_transport_t *transport = handle;
-
- if (!transport){
+
+ if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return tsk_null;
}
-
- if (!transport->dtls.enabled){
+
+ if (!transport->dtls.enabled) {
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
return tsk_null;
}
- if (hash > sizeof(transport->dtls.fingerprints) / sizeof(transport->dtls.fingerprints[0])){
+ if (hash > sizeof(transport->dtls.fingerprints) / sizeof(transport->dtls.fingerprints[0])) {
TSK_DEBUG_ERROR("%d not valid for fingerprint hash", hash);
return tsk_null;
}
- if (tsk_strnullORempty(transport->tls.pbk)){
+ if (tsk_strnullORempty(transport->tls.pbk)) {
TSK_DEBUG_ERROR("No certificate for which to get fingerprint");
return tsk_null;
}
-
- if (tnet_dtls_get_fingerprint(transport->tls.pbk, &((tnet_transport_t *)transport)->dtls.fingerprints[hash], hash) == 0){
+
+ if (tnet_dtls_get_fingerprint(transport->tls.pbk, &((tnet_transport_t *)transport)->dtls.fingerprints[hash], hash) == 0) {
return (const char*)transport->dtls.fingerprints[hash];
}
return tsk_null;
@@ -465,12 +464,12 @@ const char* tnet_transport_dtls_get_local_fingerprint(const tnet_transport_handl
int tnet_transport_dtls_use_srtp(tnet_transport_handle_t *handle, const char* srtp_profiles, struct tnet_socket_s** sockets, tsk_size_t sockets_count)
{
tnet_transport_t *transport = handle;
-
- if (!transport || !srtp_profiles){
+
+ if (!transport || !srtp_profiles) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
- if (!transport->dtls.enabled){
+ if (!transport->dtls.enabled) {
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
return -2;
}
@@ -479,9 +478,9 @@ int tnet_transport_dtls_use_srtp(tnet_transport_handle_t *handle, const char* sr
tsk_size_t i;
transport->dtls.use_srtp = tsk_true;
SSL_CTX_set_tlsext_use_srtp(transport->dtls.ctx, srtp_profiles);
- if (sockets){
- for (i = 0; i < sockets_count; ++i){
- if (sockets[i] && sockets[i]->dtlshandle){
+ if (sockets) {
+ for (i = 0; i < sockets_count; ++i) {
+ if (sockets[i] && sockets[i]->dtlshandle) {
tnet_dtls_socket_use_srtp(sockets[i]->dtlshandle);
}
}
@@ -497,20 +496,20 @@ int tnet_transport_dtls_use_srtp(tnet_transport_handle_t *handle, const char* sr
int tnet_transport_dtls_set_remote_fingerprint(tnet_transport_handle_t *handle, const tnet_fingerprint_t* fingerprint, tnet_dtls_hash_type_t hash, struct tnet_socket_s** sockets, tsk_size_t sockets_count)
{
const tnet_transport_t *transport = handle;
-
- if (!transport || !fingerprint){
+
+ if (!transport || !fingerprint) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
- if (!transport->dtls.enabled){
+ if (!transport->dtls.enabled) {
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
return -2;
}
#if HAVE_OPENSSL_DTLS
- if (sockets){
+ if (sockets) {
tsk_size_t i;
- for (i = 0; i < sockets_count; ++i){
- if (sockets[i] && sockets[i]->dtlshandle){
+ for (i = 0; i < sockets_count; ++i) {
+ if (sockets[i] && sockets[i]->dtlshandle) {
tnet_dtls_socket_set_remote_fingerprint(sockets[i]->dtlshandle, fingerprint, hash);
}
}
@@ -525,7 +524,7 @@ int tnet_transport_dtls_set_remote_fingerprint(tnet_transport_handle_t *handle,
tsk_bool_t tnet_transport_dtls_is_enabled(const tnet_transport_handle_t *handle)
{
const tnet_transport_t *transport = handle;
- if (!transport){
+ if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
@@ -545,18 +544,18 @@ int tnet_transport_dtls_set_enabled(tnet_transport_handle_t *handle, tsk_bool_t
tnet_transport_t *transport = handle;
tnet_socket_type_t type;
int ret;
-
- if (!transport){
+
+ if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
type = tnet_transport_get_type(transport);
-
+
if (enabled & !tnet_dtls_is_supported()) {
TSK_DEBUG_ERROR("Trying to enable DTLS but code source not built with this feature");
return -1;
}
-
+
if ((transport->dtls.enabled = enabled)) {
if ((ret = _tnet_transport_ssl_init(transport))) {
return ret;
@@ -565,7 +564,7 @@ int tnet_transport_dtls_set_enabled(tnet_transport_handle_t *handle, tsk_bool_t
else {
ret = _tnet_transport_ssl_deinit(transport);
}
-
+
if (sockets && sockets_count) {
tsk_size_t i;
for (i = 0; i < sockets_count; ++i) {
@@ -588,19 +587,19 @@ int tnet_transport_dtls_set_enabled(tnet_transport_handle_t *handle, tsk_bool_t
}
}
}
-
+
return ret;
}
int tnet_transport_dtls_set_setup(tnet_transport_handle_t* handle, tnet_dtls_setup_t setup, struct tnet_socket_s** sockets, tsk_size_t sockets_count)
{
tnet_transport_t *transport = handle;
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
if (!transport->dtls.enabled) {
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
return -2;
@@ -620,12 +619,12 @@ int tnet_transport_dtls_set_setup(tnet_transport_handle_t* handle, tnet_dtls_set
int tnet_transport_dtls_set_store_handshakingdata(tnet_transport_handle_t* handle, tsk_bool_t handshake_storedata, struct tnet_socket_s** sockets, tsk_size_t sockets_count)
{
tnet_transport_t *transport = handle;
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
if (!transport->dtls.enabled) {
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
return -2;
@@ -646,29 +645,29 @@ int tnet_transport_dtls_do_handshake(tnet_transport_handle_t *handle, struct tne
{
tnet_transport_t *transport = handle;
tsk_size_t i;
-
+
if (!transport || !sockets) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
if (!transport->dtls.enabled) {
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
return -2;
}
-
+
if (sockets) {
int ret;
for (i = 0; i < sockets_count; ++i) {
if (sockets[i] && sockets[i]->dtlshandle) {
if ((ret = tnet_dtls_socket_do_handshake(sockets[i]->dtlshandle,
- (remote_addrs && i < remote_addrs_count) ? remote_addrs[i] : tsk_null)) != 0){
+ (remote_addrs && i < remote_addrs_count) ? remote_addrs[i] : tsk_null)) != 0) {
return ret;
}
}
}
}
-
+
return 0;
}
@@ -676,22 +675,22 @@ int tnet_transport_dtls_get_handshakingdata(tnet_transport_handle_t* handle, con
{
tnet_transport_t *transport = handle;
tsk_size_t i;
-
+
if (!transport || !sockets) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
if (!transport->dtls.enabled) {
TSK_DEBUG_ERROR("DTLS not enabled on this transport");
return -2;
}
-
+
if (sockets) {
int ret;
for (i = 0; i < sockets_count; ++i) {
if (sockets[i] && sockets[i]->dtlshandle) {
- if ((ret = tnet_dtls_socket_get_handshakingdata(sockets[i]->dtlshandle, &data[i], &size[i])) != 0){
+ if ((ret = tnet_dtls_socket_get_handshakingdata(sockets[i]->dtlshandle, &data[i], &size[i])) != 0) {
return ret;
}
}
@@ -701,13 +700,13 @@ int tnet_transport_dtls_get_handshakingdata(tnet_transport_handle_t* handle, con
}
}
}
-
+
return 0;
}
tnet_socket_type_t tnet_transport_get_type(const tnet_transport_handle_t *handle)
{
- if (!handle){
+ if (!handle) {
TSK_DEBUG_ERROR("Invalid parameter");
return tnet_socket_type_invalid;
}
@@ -716,7 +715,7 @@ tnet_socket_type_t tnet_transport_get_type(const tnet_transport_handle_t *handle
tnet_fd_t tnet_transport_get_master_fd(const tnet_transport_handle_t *handle)
{
- if (!handle){
+ if (!handle) {
TSK_DEBUG_ERROR("Invalid parameter");
return TNET_INVALID_FD;
}
@@ -725,12 +724,16 @@ tnet_fd_t tnet_transport_get_master_fd(const tnet_transport_handle_t *handle)
int tnet_transport_get_bytes_count(const tnet_transport_handle_t *handle, uint64_t* bytes_in, uint64_t* bytes_out)
{
- if (!handle){
+ if (!handle) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
- if (bytes_in) *bytes_in = ((const tnet_transport_t *)handle)->bytes_in;
- if (bytes_out) *bytes_out = ((const tnet_transport_t *)handle)->bytes_out;
+ if (bytes_in) {
+ *bytes_in = ((const tnet_transport_t *)handle)->bytes_in;
+ }
+ if (bytes_out) {
+ *bytes_out = ((const tnet_transport_t *)handle)->bytes_out;
+ }
return 0;
}
@@ -762,18 +765,18 @@ tnet_fd_t tnet_transport_connectto_3(const tnet_transport_handle_t *handle, stru
tnet_port_t to_port = port;
tnet_socket_type_t to_type = type;
tnet_proxyinfo_t* proxy_info = tsk_null;
-
+
if (!transport || !transport->master) {
TSK_DEBUG_ERROR("Invalid transport handle");
goto bail;
}
-
+
if ((TNET_SOCKET_TYPE_IS_STREAM(transport->master->type) && !TNET_SOCKET_TYPE_IS_STREAM(type)) ||
- (TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type) && !TNET_SOCKET_TYPE_IS_DGRAM(type))) {
+ (TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type) && !TNET_SOCKET_TYPE_IS_DGRAM(type))) {
TSK_DEBUG_ERROR("Master/destination types mismatch [%u/%u]", transport->master->type, type);
goto bail;
}
-
+
if (use_proxy) {
// auto-detect the proxy
if (transport->proxy.auto_detect) {
@@ -788,7 +791,7 @@ tnet_fd_t tnet_transport_connectto_3(const tnet_transport_handle_t *handle, stru
proxy_info = tsk_object_ref(transport->proxy.info);
}
}
-
+
use_proxy &= tnet_proxyinfo_is_valid(proxy_info);
if (use_proxy) {
if (tnet_proxy_node_is_nettransport_supported(proxy_info->type, type)) {
@@ -807,9 +810,9 @@ tnet_fd_t tnet_transport_connectto_3(const tnet_transport_handle_t *handle, stru
use_proxy = tsk_false;
}
}
-
+
TSK_DEBUG_INFO("tnet_transport_connectto_3(host=%s, port=%d, type=%d, fd=%d, use_proxy=%d, to_host=%s, to_port=%d, to_type=%d, proxy_type=%d)" , host, port, type, fd, use_proxy, to_host, to_port, to_type, proxy_info ? proxy_info->type : 0);
-
+
/* Init destination sockaddr fields */
if ((status = tnet_sockaddr_init(to_host, to_port, to_type, &to))) {
TSK_DEBUG_ERROR("Invalid HOST/PORT [%s/%u]", host, port);
@@ -824,7 +827,7 @@ tnet_fd_t tnet_transport_connectto_3(const tnet_transport_handle_t *handle, stru
TNET_SOCKET_TYPE_SET_IPV4Only(type);
}
}
-
+
/*
* STREAM ==> create new socket and connect it to the remote host.
* DGRAM ==> connect the master to the remote host.
@@ -836,7 +839,7 @@ tnet_fd_t tnet_transport_connectto_3(const tnet_transport_handle_t *handle, stru
goto bail;
}
}
-
+
if ((status = tnet_sockfd_connectto(fd, (const struct sockaddr_storage *)&to))) {
if (fd != transport->master->fd) {
tnet_sockfd_close(&fd);
@@ -866,7 +869,7 @@ tnet_fd_t tnet_transport_connectto_3(const tnet_transport_handle_t *handle, stru
goto bail;
}
}
-
+
bail:
TSK_OBJECT_SAFE_FREE(tls_handle);
TSK_OBJECT_SAFE_FREE(proxy_info);
@@ -876,12 +879,12 @@ bail:
int tnet_transport_set_callback(const tnet_transport_handle_t *handle, tnet_transport_cb_f callback, const void* callback_data)
{
tnet_transport_t *transport = (tnet_transport_t*)handle;
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid server handle.");
return -1;
}
-
+
transport->callback = callback;
transport->callback_data = callback_data;
return 0;
@@ -912,7 +915,7 @@ int tnet_transport_set_proxy_info(tnet_transport_handle_t *handle, enum tnet_pro
proxy_info->port = port;
proxy_info->username = tsk_strdup(login);
proxy_info->password = tsk_strdup(password);
-
+
TSK_OBJECT_SAFE_FREE(transport->proxy.info);
transport->proxy.info = proxy_info;
return 0;
@@ -927,7 +930,7 @@ int tnet_transport_shutdown(tnet_transport_handle_t* handle)
{
if (handle) {
int ret;
- if ((ret = tnet_transport_stop(handle)) == 0){
+ if ((ret = tnet_transport_stop(handle)) == 0) {
ret = tnet_transport_unprepare(handle);
}
return ret;
@@ -947,16 +950,32 @@ static int _tnet_transport_dtls_cb(const void* usrdata, tnet_dtls_socket_event_t
const struct sockaddr_storage* remote_addr;
tnet_fd_t fd;
tnet_transport_event_t* e;
-
+
switch (dtls_e) {
- case tnet_dtls_socket_event_type_handshake_started: t_e = event_dtls_handshake_started; break;
- case tnet_dtls_socket_event_type_handshake_succeed: t_e = event_dtls_handshake_succeed; break;
- case tnet_dtls_socket_event_type_handshake_failed: t_e = event_dtls_handshake_failed; break;
- case tnet_dtls_socket_event_type_fingerprint_mismatch: t_e = event_dtls_fingerprint_mismatch; break;
- case tnet_dtls_socket_event_type_dtls_srtp_profile_selected: t_e = event_dtls_srtp_profile_selected; break;
- case tnet_dtls_socket_event_type_dtls_srtp_data: t_e = event_dtls_srtp_data; break;
- case tnet_dtls_socket_event_type_error: t_e = event_dtls_error; break;
- default: TSK_DEBUG_ERROR("DTLS event = %d ignored", dtls_e); return -1;
+ case tnet_dtls_socket_event_type_handshake_started:
+ t_e = event_dtls_handshake_started;
+ break;
+ case tnet_dtls_socket_event_type_handshake_succeed:
+ t_e = event_dtls_handshake_succeed;
+ break;
+ case tnet_dtls_socket_event_type_handshake_failed:
+ t_e = event_dtls_handshake_failed;
+ break;
+ case tnet_dtls_socket_event_type_fingerprint_mismatch:
+ t_e = event_dtls_fingerprint_mismatch;
+ break;
+ case tnet_dtls_socket_event_type_dtls_srtp_profile_selected:
+ t_e = event_dtls_srtp_profile_selected;
+ break;
+ case tnet_dtls_socket_event_type_dtls_srtp_data:
+ t_e = event_dtls_srtp_data;
+ break;
+ case tnet_dtls_socket_event_type_error:
+ t_e = event_dtls_error;
+ break;
+ default:
+ TSK_DEBUG_ERROR("DTLS event = %d ignored", dtls_e);
+ return -1;
}
remote_addr = tnet_dtls_socket_get_remote_addr(handle);
fd = tnet_dtls_socket_get_fd(handle);
@@ -994,11 +1013,11 @@ static void* TSK_STDCALL run(void* self)
int ret = 0;
tsk_list_item_t *curr;
tnet_transport_t *transport = self;
-
+
TSK_DEBUG_INFO("Transport::run(%s) - enter", transport->description);
-
+
/* create main thread */
- if ((ret = tsk_thread_create(transport->mainThreadId, tnet_transport_mainthread, transport))){ /* More important than "tsk_runnable_start" ==> start it first. */
+ if ((ret = tsk_thread_create(transport->mainThreadId, tnet_transport_mainthread, transport))) { /* More important than "tsk_runnable_start" ==> start it first. */
TSK_FREE(transport->context); /* Otherwise (tsk_thread_create is ok) will be freed when mainthread exit. */
TSK_DEBUG_FATAL("Failed to create main thread [%d]", ret);
return tsk_null;
@@ -1009,22 +1028,22 @@ static void* TSK_STDCALL run(void* self)
#if !TNET_UNDER_APPLE
ret = tsk_thread_set_priority(transport->mainThreadId[0], TSK_THREAD_PRIORITY_TIME_CRITICAL);
#endif
-
+
TSK_RUNNABLE_RUN_BEGIN(transport);
-
- if ((curr = TSK_RUNNABLE_POP_FIRST_SAFE(TSK_RUNNABLE(transport)))){
+
+ if ((curr = TSK_RUNNABLE_POP_FIRST_SAFE(TSK_RUNNABLE(transport)))) {
const tnet_transport_event_t *e = (const tnet_transport_event_t*)curr->data;
-
+
if (transport->callback) {
transport->callback(e);
}
tsk_object_unref(curr);
}
-
+
TSK_RUNNABLE_RUN_END(transport);
-
+
TSK_DEBUG_INFO("Transport::run(%s) - exit", transport->description);
-
+
return tsk_null;
}
@@ -1037,7 +1056,7 @@ static void* TSK_STDCALL run(void* self)
static tsk_object_t* tnet_transport_ctor(tsk_object_t * self, va_list * app)
{
tnet_transport_t *transport = self;
- if (transport){
+ if (transport) {
}
return self;
}
@@ -1045,7 +1064,7 @@ static tsk_object_t* tnet_transport_ctor(tsk_object_t * self, va_list * app)
static tsk_object_t* tnet_transport_dtor(tsk_object_t * self)
{
tnet_transport_t *transport = self;
- if (transport){
+ if (transport) {
tnet_transport_set_callback(transport, tsk_null, tsk_null);
tnet_transport_shutdown(transport);
TSK_OBJECT_SAFE_FREE(transport->master);
@@ -1053,25 +1072,24 @@ static tsk_object_t* tnet_transport_dtor(tsk_object_t * self)
TSK_OBJECT_SAFE_FREE(transport->natt_ctx);
TSK_FREE(transport->local_ip);
TSK_FREE(transport->local_host);
-
+
// proxy
TSK_OBJECT_SAFE_FREE(transport->proxy.info);
-
+
// (tls and dtls) = ssl
TSK_FREE(transport->tls.ca);
TSK_FREE(transport->tls.pbk);
TSK_FREE(transport->tls.pvk);
_tnet_transport_ssl_deinit(transport); // openssl contexts
-
+
TSK_DEBUG_INFO("*** Transport (%s) destroyed ***", transport->description);
TSK_FREE(transport->description);
}
-
+
return self;
}
-static const tsk_object_def_t tnet_transport_def_s =
-{
+static const tsk_object_def_t tnet_transport_def_s = {
sizeof(tnet_transport_t),
tnet_transport_ctor,
tnet_transport_dtor,
@@ -1087,7 +1105,7 @@ const tsk_object_def_t *tnet_transport_def_t = &tnet_transport_def_s;
static tsk_object_t* tnet_transport_event_ctor(tsk_object_t * self, va_list * app)
{
tnet_transport_event_t *e = self;
- if (e){
+ if (e) {
e->type = va_arg(*app, tnet_transport_event_type_t);
e->callback_data = va_arg(*app, const void*);
e->local_fd = va_arg(*app, tnet_fd_t);
@@ -1098,15 +1116,14 @@ static tsk_object_t* tnet_transport_event_ctor(tsk_object_t * self, va_list * ap
static tsk_object_t* tnet_transport_event_dtor(tsk_object_t * self)
{
tnet_transport_event_t *e = self;
- if (e){
+ if (e) {
TSK_FREE(e->data);
}
-
+
return self;
}
-static const tsk_object_def_t tnet_transport_event_def_s =
-{
+static const tsk_object_def_t tnet_transport_event_def_s = {
sizeof(tnet_transport_event_t),
tnet_transport_event_ctor,
tnet_transport_event_dtor,
diff --git a/tinyNET/src/tnet_transport.h b/tinyNET/src/tnet_transport.h
index c4da35b..f86829c 100755
--- a/tinyNET/src/tnet_transport.h
+++ b/tinyNET/src/tnet_transport.h
@@ -41,38 +41,36 @@ TNET_BEGIN_DECLS
#define TNET_TRANSPORT_CB_F(callback) ((tnet_transport_cb_f)callback)
-typedef enum tnet_transport_event_type_e
-{
- event_data,
- event_closed,
- event_error,
- event_removed,
- event_connected,
- event_accepted,
+typedef enum tnet_transport_event_type_e {
+ event_data,
+ event_closed,
+ event_error,
+ event_removed,
+ event_connected,
+ event_accepted,
event_brokenpipe, // iOS: UDP sockets closed, to be restored now that the app is on foreground
- event_dtls_handshake_started,
- event_dtls_handshake_succeed,
- event_dtls_handshake_failed,
- event_dtls_fingerprint_mismatch,
- event_dtls_srtp_data,
- event_dtls_srtp_profile_selected,
- event_dtls_error
+ event_dtls_handshake_started,
+ event_dtls_handshake_succeed,
+ event_dtls_handshake_failed,
+ event_dtls_fingerprint_mismatch,
+ event_dtls_srtp_data,
+ event_dtls_srtp_profile_selected,
+ event_dtls_error
}
tnet_transport_event_type_t;
-typedef struct tnet_transport_event_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_transport_event_s {
+ TSK_DECLARE_OBJECT;
- tnet_transport_event_type_t type;
+ tnet_transport_event_type_t type;
- void* data;
- tsk_size_t size;
+ void* data;
+ tsk_size_t size;
- const void* callback_data;
- tnet_fd_t local_fd;
- struct sockaddr_storage remote_addr;
+ const void* callback_data;
+ tnet_fd_t local_fd;
+ struct sockaddr_storage remote_addr;
}
tnet_transport_event_t;
@@ -123,52 +121,51 @@ TINYNET_API tnet_fd_t tnet_transport_get_master_fd(const tnet_transport_handle_t
TINYNET_API int tnet_transport_get_bytes_count(const tnet_transport_handle_t *handle, uint64_t* bytes_in, uint64_t* bytes_out);
TINYNET_API int tnet_transport_shutdown(tnet_transport_handle_t* handle);
-typedef struct tnet_transport_s
-{
- TSK_DECLARE_RUNNABLE;
-
- tnet_socket_type_t type;
- char* local_ip;
- char* local_host;
- tnet_port_t req_local_port; // user requested local port
- tnet_port_t bind_local_port; // local port on which we are listening (same as master socket)
- struct tnet_nat_ctx_s* natt_ctx;
- tnet_socket_t *master;
-
- tsk_object_t *context;
- tsk_bool_t prepared;
-
+typedef struct tnet_transport_s {
+ TSK_DECLARE_RUNNABLE;
+
+ tnet_socket_type_t type;
+ char* local_ip;
+ char* local_host;
+ tnet_port_t req_local_port; // user requested local port
+ tnet_port_t bind_local_port; // local port on which we are listening (same as master socket)
+ struct tnet_nat_ctx_s* natt_ctx;
+ tnet_socket_t *master;
+
+ tsk_object_t *context;
+ tsk_bool_t prepared;
+
uint64_t bytes_out;
uint64_t bytes_in;
- //unsigned connected:1;
- void* mainThreadId[1];
-
- char *description;
-
- tnet_transport_cb_f callback;
- const void* callback_data;
-
- /* TLS certs */
- struct {
- char* ca;
- char* pvk;
- char* pbk;
- tsk_bool_t enabled;
- tsk_bool_t verify; // whether to verify client/server certificate
- struct ssl_ctx_st *ctx_client;
- struct ssl_ctx_st *ctx_server;
- }tls;
-
- /* DTLS */
- struct{
- tsk_bool_t enabled;
- tsk_bool_t activated;
- tsk_bool_t use_srtp;
- struct ssl_ctx_st *ctx;
- tnet_fingerprint_t fingerprints[TNET_DTLS_HASH_TYPE_MAX];
- }dtls;
-
+ //unsigned connected:1;
+ void* mainThreadId[1];
+
+ char *description;
+
+ tnet_transport_cb_f callback;
+ const void* callback_data;
+
+ /* TLS certs */
+ struct {
+ char* ca;
+ char* pvk;
+ char* pbk;
+ tsk_bool_t enabled;
+ tsk_bool_t verify; // whether to verify client/server certificate
+ struct ssl_ctx_st *ctx_client;
+ struct ssl_ctx_st *ctx_server;
+ } tls;
+
+ /* DTLS */
+ struct {
+ tsk_bool_t enabled;
+ tsk_bool_t activated;
+ tsk_bool_t use_srtp;
+ struct ssl_ctx_st *ctx;
+ tnet_fingerprint_t fingerprints[TNET_DTLS_HASH_TYPE_MAX];
+ } dtls;
+
/* PROXY */
struct {
tsk_bool_t auto_detect;
diff --git a/tinyNET/src/tnet_transport_cfsocket.c b/tinyNET/src/tnet_transport_cfsocket.c
index 4115b22..ed844b6 100755
--- a/tinyNET/src/tnet_transport_cfsocket.c
+++ b/tinyNET/src/tnet_transport_cfsocket.c
@@ -55,25 +55,24 @@
#define TNET_BUFFER_STREAM_MIN_SIZE 1024
/*== Socket description ==*/
-typedef struct transport_socket_xs
-{
+typedef struct transport_socket_xs {
tnet_fd_t fd;
tsk_bool_t owner;
tsk_bool_t readable;
tsk_bool_t writable;
tsk_bool_t paused;
tsk_bool_t is_client;
-
+
tnet_proxy_node_t *proxy_node;
tnet_proxyinfo_t* proxy_info;
tsk_bool_t proxy_handshacking_completed;
tsk_bool_t proxy_handshacking_started;
-
+
char* dst_host;
tnet_port_t dst_port;
-
+
tnet_socket_type_t type;
-
+
CFSocketRef cf_socket;
CFReadStreamRef cf_read_stream;
CFWriteStreamRef cf_write_stream;
@@ -82,15 +81,14 @@ typedef struct transport_socket_xs
transport_socket_xt;
/*== Transport context structure definition ==*/
-typedef struct transport_context_s
-{
+typedef struct transport_context_s {
TSK_DECLARE_OBJECT;
-
+
tsk_size_t count;
transport_socket_xt* sockets[TNET_MAX_FDS];
-
+
CFRunLoopRef cf_run_loop;
-
+
TSK_DECLARE_SAFEOBJ;
}
transport_context_t;
@@ -114,32 +112,32 @@ static BOOL isTrusted(tnet_transport_t *transport, id cfStream, BOOL bReadStream
SecCertificateRef certArray[2] = { NULL, NULL };
CFArrayRef refCertArray = NULL;
CFIndex certArrayCount = 0;
-
+
trust = bReadStream
- ? (SecTrustRef)CFReadStreamCopyProperty((CFReadStreamRef)cfStream, kCFStreamPropertySSLPeerTrust)
- : (SecTrustRef)CFWriteStreamCopyProperty((CFWriteStreamRef)cfStream, kCFStreamPropertySSLPeerTrust);
+ ? (SecTrustRef)CFReadStreamCopyProperty((CFReadStreamRef)cfStream, kCFStreamPropertySSLPeerTrust)
+ : (SecTrustRef)CFWriteStreamCopyProperty((CFWriteStreamRef)cfStream, kCFStreamPropertySSLPeerTrust);
if (!trust) {
TSK_DEBUG_ERROR("Failed to get SecTrustRef object from '%s' stream", bReadStream ? "read" : "write");
goto bail;
}
-
+
NSString *caName = NULL, *pbName = NULL;
-
+
if (!tsk_strnullORempty(transport->tls.ca)) {
- caName = [[[NSString stringWithCString:transport->tls.ca encoding: NSUTF8StringEncoding] lastPathComponent] stringByDeletingPathExtension];
+caName = [[[NSString stringWithCString:transport->tls.ca encoding: NSUTF8StringEncoding] lastPathComponent] stringByDeletingPathExtension];
}
if (!tsk_strnullORempty(transport->tls.pbk)) {
- pbName = [[[NSString stringWithCString:transport->tls.pbk encoding: NSUTF8StringEncoding] lastPathComponent] stringByDeletingPathExtension];
+pbName = [[[NSString stringWithCString:transport->tls.pbk encoding: NSUTF8StringEncoding] lastPathComponent] stringByDeletingPathExtension];
}
TSK_DEBUG_INFO("SSL::isTrusted(ca=%s, pb=%s)", [caName UTF8String], [pbName UTF8String]);
-
+
if (caName) {
- NSString *caPath = [[NSBundle mainBundle] pathForResource:caName ofType:@"der"];
- if (![[NSFileManager defaultManager] fileExistsAtPath:caPath]) {
+NSString *caPath = [[NSBundle mainBundle] pathForResource:caName ofType:@"der"];
+if (![[NSFileManager defaultManager] fileExistsAtPath:caPath]) {
TSK_DEBUG_WARN("Cannot find SSL CA file '%s.der'", [caPath UTF8String]);
}
else {
- NSData *certData = [[NSData alloc] initWithContentsOfFile:caPath];
+NSData *certData = [[NSData alloc] initWithContentsOfFile:caPath];
CFDataRef certDataRef = (CFDataRef)certData;
SecCertificateRef cert = certDataRef ? SecCertificateCreateWithData(NULL, certDataRef) : NULL;
[certData release];
@@ -153,12 +151,12 @@ static BOOL isTrusted(tnet_transport_t *transport, id cfStream, BOOL bReadStream
}
}
if (pbName) {
- NSString *pbPath = [[NSBundle mainBundle] pathForResource:pbName ofType:@"der"];
- if (![[NSFileManager defaultManager] fileExistsAtPath:pbPath]) {
+NSString *pbPath = [[NSBundle mainBundle] pathForResource:pbName ofType:@"der"];
+if (![[NSFileManager defaultManager] fileExistsAtPath:pbPath]) {
TSK_DEBUG_WARN("Cannot find SSL PUB file '%s.der'", [pbPath UTF8String]);
}
else {
- NSData *certData = [[NSData alloc] initWithContentsOfFile:pbPath];
+NSData *certData = [[NSData alloc] initWithContentsOfFile:pbPath];
CFDataRef certDataRef = (CFDataRef)certData;
SecCertificateRef cert = certDataRef ? SecCertificateCreateWithData(NULL, certDataRef) : NULL;
[certData release];
@@ -191,7 +189,7 @@ static BOOL isTrusted(tnet_transport_t *transport, id cfStream, BOOL bReadStream
}
bTrusted = (result == kSecTrustResultProceed || result == kSecTrustResultUnspecified);
TSK_DEBUG_INFO("SecTrustEvaluate result = %d", result);
-
+
bail:
CFRelease(trust);
CFRelease(refCertArray);
@@ -202,28 +200,28 @@ bail:
static int recvData(tnet_transport_t *transport, transport_socket_xt* active_socket)
{
int ret;
- if(!transport || !transport->context || !active_socket){
+ if(!transport || !transport->context || !active_socket) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
void* buffer = tsk_null;
tsk_size_t len = 0;
struct sockaddr_storage remote_addr = {0};
-
+
/* check whether the socket is paused or not */
if (active_socket->paused) {
TSK_DEBUG_INFO("Socket is paused");
goto bail;
}
-
+
tsk_bool_t is_stream = TNET_SOCKET_TYPE_IS_STREAM(active_socket->type);
-
+
if (tnet_ioctlt(active_socket->fd, FIONREAD, &len) < 0) {
TNET_PRINT_LAST_ERROR("ioctl() failed");
goto bail;
}
-
+
if (!len) {
// probably incoming connection
if (is_stream && !active_socket->is_client) {
@@ -235,26 +233,26 @@ static int recvData(tnet_transport_t *transport, transport_socket_xt* active_soc
goto bail;
}
}
-
+
if (is_stream && CFReadStreamHasBytesAvailable(active_socket->cf_read_stream)) {
if ((buffer = tsk_calloc(TNET_BUFFER_STREAM_MIN_SIZE, sizeof(uint8_t)))) {
len = CFReadStreamRead(active_socket->cf_read_stream, buffer, (CFIndex)TNET_BUFFER_STREAM_MIN_SIZE);
ret = (int)len;
}
}
-
+
if (ret <= 0) {
TSK_DEBUG_WARN("ioctl() returned zero for fd=%d", active_socket->fd);
goto bail;
}
}
-
+
if (len && !buffer) {
- if(!(buffer = tsk_calloc(len, sizeof(uint8_t)))){
+ if(!(buffer = tsk_calloc(len, sizeof(uint8_t)))) {
TSK_DEBUG_ERROR("calloc(%zu) failed", len);
goto bail;
}
-
+
// Receive the waiting data
if (is_stream) {
ret = tnet_getpeername(active_socket->fd, &remote_addr);
@@ -269,23 +267,23 @@ static int recvData(tnet_transport_t *transport, transport_socket_xt* active_soc
ret = tnet_sockfd_recvfrom(active_socket->fd, buffer, len, 0, (struct sockaddr*)&remote_addr);
}
}
-
-
- if(ret < 0){
+
+
+ if(ret < 0) {
removeSocket(active_socket, transport->context);
TNET_PRINT_LAST_ERROR("recv/recvfrom have failed.");
goto bail;
}
-
+
if ((len != (tsk_size_t)ret) && len) {
len = (tsk_size_t)ret;
}
-
+
if (!active_socket->proxy_handshacking_completed && active_socket->proxy_handshacking_started && active_socket->proxy_node && active_socket->proxy_info) {
void* handshaking_data_ptr = tsk_null;
tsk_size_t handshaking_data_size = 0;
TSK_DEBUG_INFO("Proxy handshaking data:%.*s", (int)len, buffer);
-
+
// handle incoming hadshaking data
if ((ret = tnet_proxy_node_set_handshaking_data(active_socket->proxy_node, buffer, len)) != 0) {
TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
@@ -318,18 +316,19 @@ static int recvData(tnet_transport_t *transport, transport_socket_xt* active_soc
}
goto bail; // do not forward the data to the end-user
}
-
+
if (len && buffer) {
tnet_transport_event_t* e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
if (e && buffer && len) {
- e->data = buffer; buffer = NULL;
+ e->data = buffer;
+ buffer = NULL;
e->size = len;
e->remote_addr = remote_addr;
-
+
TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
}
}
-
+
bail:
TSK_FREE(buffer);
return 0;
@@ -341,31 +340,31 @@ int tnet_transport_add_socket_2(const tnet_transport_handle_t *handle, tnet_fd_t
transport_context_t* context;
int ret = -1;
(void)(tlsHandle);
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid server handle.");
return ret;
}
-
+
if (!(context = (transport_context_t*)transport->context)) {
TSK_DEBUG_ERROR("Invalid context.");
return -2;
}
-
- if(TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)){
+
+ if(TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)) {
transport->tls.enabled = 1;
}
-
+
if ((ret = addSocket2(fd, type, transport, take_ownership, isClient, dst_host, dst_port, proxy_info))) {
TSK_DEBUG_ERROR("Failed to add new Socket.");
return ret;
}
-
+
if (context->cf_run_loop) {
// Signal the run-loop
CFRunLoopWakeUp(context->cf_run_loop);
}
-
+
return 0;
}
@@ -377,23 +376,24 @@ int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t f
return tnet_transport_add_socket_2(handle, fd, type, take_ownership, isClient, tlsHandle, __dst_host_null, __dst_port_zero, __proxy_info_null);
}
-int tnet_transport_pause_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tsk_bool_t pause){
+int tnet_transport_pause_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tsk_bool_t pause)
+{
tnet_transport_t *transport = (tnet_transport_t*)handle;
transport_context_t *context;
transport_socket_xt* socket;
-
- if(!transport || !(context = (transport_context_t *)transport->context)){
+
+ if(!transport || !(context = (transport_context_t *)transport->context)) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
- if((socket = (transport_socket_xt*)getSocket(context, fd))){
+
+ if((socket = (transport_socket_xt*)getSocket(context, fd))) {
socket->paused = pause;
}
else {
TSK_DEBUG_WARN("Failed to find socket with fd=%d", (int)fd);
}
-
+
return 0;
}
@@ -404,19 +404,19 @@ int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_
transport_context_t *context;
tsk_size_t i;
tsk_bool_t found = tsk_false;
-
+
if (!transport || !fd) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
TSK_DEBUG_INFO("Removing socket %d", *fd);
-
+
if (!(context = (transport_context_t*)transport->context)) {
TSK_DEBUG_ERROR("Invalid context.");
return -2;
}
-
+
for(i=0; i<context->count; ++i) {
if (context->sockets[i]->fd == *fd) {
removeSocketAtIndex((int)i, context);
@@ -425,15 +425,15 @@ int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_
break;
}
}
-
+
if (found && context->cf_run_loop) {
// Signal the run-loop
CFRunLoopWakeUp(context->cf_run_loop);
return 0;
}
-
+
// ...
-
+
return -1;
}
@@ -441,29 +441,29 @@ tsk_size_t tnet_transport_send(const tnet_transport_handle_t *handle, tnet_fd_t
{
tnet_transport_t *transport = (tnet_transport_t*)handle;
int numberOfBytesSent = 0;
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid transport handle.");
goto bail;
}
-
+
const transport_socket_xt* sock = getSocket(transport->context, from);
if (sock && sock->cf_write_stream && TNET_SOCKET_TYPE_IS_STREAM(sock->type) && sock->cf_write_stream) {
int sent = 0, to_send;
const uint8_t* buff_ptr = (const uint8_t*)buf;
// on iOS when TLS is enabled sending more than 1024 bytes could fails
static const int max_size_to_send = 1024;
-
+
to_send = (int)TSK_MIN(max_size_to_send, size);
-
+
if (CFWriteStreamGetStatus(sock->cf_write_stream) == kCFStreamStatusNotOpen) {
- if(!CFWriteStreamOpen(sock->cf_write_stream)){
+ if(!CFWriteStreamOpen(sock->cf_write_stream)) {
TSK_DEBUG_ERROR("CFWriteStreamOpen() failed");
return numberOfBytesSent;
}
}
if (CFReadStreamGetStatus(sock->cf_read_stream) == kCFStreamStatusNotOpen) {
- if(!CFReadStreamOpen(sock->cf_read_stream)){
+ if(!CFReadStreamOpen(sock->cf_read_stream)) {
TSK_DEBUG_ERROR("CFReadStreamOpen() failed");
return numberOfBytesSent;
}
@@ -472,17 +472,18 @@ tsk_size_t tnet_transport_send(const tnet_transport_handle_t *handle, tnet_fd_t
numberOfBytesSent += sent;
to_send = (int)TSK_MIN(max_size_to_send, (size - numberOfBytesSent));
}
- if(sent < 0){
+ if(sent < 0) {
TNET_PRINT_LAST_ERROR("Send have failed");
goto bail;
}
- } else {
+ }
+ else {
if ((numberOfBytesSent = (int)send(from, buf, size, 0)) < size) {
TNET_PRINT_LAST_ERROR("Send have failed");
goto bail;
}
}
-
+
bail:
return numberOfBytesSent;
}
@@ -491,17 +492,17 @@ tsk_size_t tnet_transport_sendto(const tnet_transport_handle_t *handle, tnet_fd_
{
tnet_transport_t *transport = (tnet_transport_t*)handle;
int numberOfBytesSent = 0, ret;
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid server handle");
goto bail;
}
-
+
if (!TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)) {
TSK_DEBUG_ERROR("In order to use sendto you must use an udp transport");
goto bail;
}
-
+
while (numberOfBytesSent < size && (ret = (int)sendto(from, buf, size, 0, to, tnet_get_sockaddr_size(to))) >= 0) {
numberOfBytesSent += ret;
}
@@ -514,7 +515,7 @@ tsk_size_t tnet_transport_sendto(const tnet_transport_handle_t *handle, tnet_fd_
TNET_PRINT_LAST_ERROR("sendto(fd=%d) have failed", from);
}
}
-
+
bail:
return numberOfBytesSent;
}
@@ -522,20 +523,20 @@ bail:
int tnet_transport_have_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd)
{
tnet_transport_t *transport = (tnet_transport_t*)handle;
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid server handle.");
return 0;
}
-
+
return (getSocket((transport_context_t*)transport->context, fd) != 0);
}
const tnet_tls_socket_handle_t* tnet_transport_get_tlshandle(const tnet_transport_handle_t *handle, tnet_fd_t fd)
{
tnet_transport_t *transport = (tnet_transport_t*)handle;
-
- if(!transport){
+
+ if(!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return 0;
}
@@ -548,7 +549,7 @@ static const transport_socket_xt* getSocket(transport_context_t *context, tnet_f
{
tsk_size_t i;
transport_socket_xt* ret = tsk_null;
-
+
if (context) {
tsk_safeobj_lock(context);
for(i=0; i<context->count; i++) {
@@ -559,14 +560,14 @@ static const transport_socket_xt* getSocket(transport_context_t *context, tnet_f
}
tsk_safeobj_unlock(context);
}
-
+
return ret;
}
static const transport_socket_xt* getSocketByStream(transport_context_t *context, void* cf_stream)
{
tsk_size_t i;
transport_socket_xt* ret = tsk_null;
-
+
if (context) {
tsk_safeobj_lock(context);
for(i=0; i<context->count; i++) {
@@ -577,13 +578,14 @@ static const transport_socket_xt* getSocketByStream(transport_context_t *context
}
tsk_safeobj_unlock(context);
}
-
+
return ret;
}
/*== Add new socket ==*/
-int addSocket2(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client , const char* dst_host, tnet_port_t dst_port, struct tnet_proxyinfo_s* proxy_info) {
+int addSocket2(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client , const char* dst_host, tnet_port_t dst_port, struct tnet_proxyinfo_s* proxy_info)
+{
transport_context_t *context = transport?transport->context:0;
if (context) {
transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
@@ -596,24 +598,24 @@ int addSocket2(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transpor
if (dst_host && dst_port && tnet_proxyinfo_is_valid(proxy_info)) {
sock->proxy_info = tsk_object_ref(proxy_info);
}
-
+
if (!sock) {
TSK_DEBUG_ERROR("Failed to allocate socket");
return -1;
}
-
+
tsk_safeobj_lock(context);
wrapSocket(transport, sock);
context->sockets[context->count] = sock;
context->count++;
-
+
tsk_safeobj_unlock(context);
-
+
TSK_DEBUG_INFO("Socket added");
-
+
return 0;
}
- else{
+ else {
TSK_DEBUG_ERROR("Context is Null.");
return -1;
}
@@ -631,19 +633,19 @@ int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport
int removeSocketAtIndex(int index, transport_context_t *context)
{
int i;
-
+
tsk_safeobj_lock(context);
-
+
if (index < (int)context->count) {
transport_socket_xt *sock = context->sockets[index];
tnet_fd_t fd = sock->fd;
-
+
// Remove from runloop
if (context->cf_run_loop && sock->cf_run_loop_source) {
CFRunLoopRemoveSource(context->cf_run_loop, sock->cf_run_loop_source, kCFRunLoopCommonModes);
CFRelease(sock->cf_run_loop_source), sock->cf_run_loop_source = NULL;
}
-
+
// Invalidate CFSocket
if (sock->cf_socket) {
if (CFSocketIsValid(sock->cf_socket)) {
@@ -652,7 +654,7 @@ int removeSocketAtIndex(int index, transport_context_t *context)
CFRelease(sock->cf_socket);
sock->cf_socket = NULL;
}
-
+
// Close and free write stream
if (sock->cf_write_stream) {
if (CFWriteStreamGetStatus(sock->cf_write_stream) != kCFStreamStatusClosed) {
@@ -661,7 +663,7 @@ int removeSocketAtIndex(int index, transport_context_t *context)
CFRelease(sock->cf_write_stream);
sock->cf_write_stream = NULL;
}
-
+
// Close and free read stream
if (sock->cf_read_stream) {
if (CFReadStreamGetStatus(sock->cf_read_stream) != kCFStreamStatusClosed) {
@@ -670,38 +672,38 @@ int removeSocketAtIndex(int index, transport_context_t *context)
CFRelease(sock->cf_read_stream);
sock->cf_read_stream = NULL;
}
-
+
// Close the socket if we are the owner.
if (sock->owner) {
tnet_sockfd_close(&(sock->fd));
}
-
+
TSK_FREE(sock->dst_host);
TSK_OBJECT_SAFE_FREE(sock->proxy_node);
TSK_OBJECT_SAFE_FREE(sock->proxy_info);
TSK_FREE(sock);
-
+
for (i = index ; i<context->count-1; ++i) {
context->sockets[i] = context->sockets[i+1];
}
-
+
context->sockets[context->count-1] = tsk_null;
context->count--;
-
+
TSK_DEBUG_INFO("Socket removed: %d", fd);
}
-
+
tsk_safeobj_unlock(context);
-
+
return 0;
}
int removeSocket(transport_socket_xt *value, transport_context_t *context)
{
int i;
-
+
tsk_safeobj_lock(context);
-
+
for(i = 0; i < context->count; i++) {
transport_socket_xt *sock = context->sockets[i];
if (sock == value) {
@@ -709,9 +711,9 @@ int removeSocket(transport_socket_xt *value, transport_context_t *context)
break;
}
}
-
+
tsk_safeobj_unlock(context);
-
+
return 0;
}
@@ -719,19 +721,19 @@ int tnet_transport_stop(tnet_transport_t *transport)
{
int ret;
transport_context_t *context;
-
+
if (!transport) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
context = transport->context;
-
+
if ((ret = tsk_runnable_stop(TSK_RUNNABLE(transport)))) {
return ret;
}
-
- if(transport->mainThreadId[0]){
+
+ if(transport->mainThreadId[0]) {
if (context && context->cf_run_loop) {
// Signal the run-loop
CFRunLoopWakeUp(context->cf_run_loop);
@@ -747,29 +749,29 @@ int tnet_transport_prepare(tnet_transport_t *transport)
{
int ret = -1;
transport_context_t *context;
-
+
if (!transport || !(context = transport->context)) {
TSK_DEBUG_ERROR("Invalid parameter.");
return -1;
}
-
+
if (transport->prepared) {
TSK_DEBUG_ERROR("Transport already prepared.");
return -2;
}
-
+
/* Prepare master */
- if(!transport->master){
- if((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))){
+ if(!transport->master) {
+ if((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))) {
tsk_strupdate(&transport->local_ip, transport->master->ip);
transport->bind_local_port = transport->master->port;
}
- else{
+ else {
TSK_DEBUG_ERROR("Failed to create master socket");
return -3;
}
}
-
+
/* Start listening */
if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
if ((ret = tnet_sockfd_listen(transport->master->fd, TNET_MAX_FDS))) {
@@ -777,7 +779,7 @@ int tnet_transport_prepare(tnet_transport_t *transport)
goto bail;
}
}
-
+
/* Add the master socket to the context. */
// don't take ownership: will be closed by the dtor() when refCount==0
// otherwise will be cosed twice: dtor() and removeSocket
@@ -785,281 +787,275 @@ int tnet_transport_prepare(tnet_transport_t *transport)
TSK_DEBUG_ERROR("Failed to add master socket");
goto bail;
}
-
+
transport->prepared = tsk_true;
-
+
bail:
return ret;
}
-int tnet_transport_unprepare(tnet_transport_t *transport){
+int tnet_transport_unprepare(tnet_transport_t *transport)
+{
transport_context_t *context;
-
- if(!transport || !(context = transport->context)){
+
+ if(!transport || !(context = transport->context)) {
TSK_DEBUG_ERROR("Invalid parameter.");
return -1;
}
-
- if(!transport->prepared){
+
+ if(!transport->prepared) {
return 0;
}
-
+
transport->prepared = tsk_false;
-
- while(context->count){
+
+ while(context->count) {
removeSocketAtIndex(0, context); // safe
}
-
+
// destroy master as it has been closed by removeSocket()
TSK_OBJECT_SAFE_FREE(transport->master);
-
+
return 0;
}
-void __CFReadStreamClientCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) {
+void __CFReadStreamClientCallBack(CFReadStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo)
+{
// Extract the context
tnet_transport_t *transport = (tnet_transport_t *) clientCallBackInfo;
transport_context_t *context = transport->context;
-
+
/* lock context */
tsk_safeobj_lock(context);
-
+
// Extract the native socket
CFDataRef data = CFReadStreamCopyProperty(stream, kCFStreamPropertySocketNativeHandle);
transport_socket_xt *sock = tsk_null;
- if(data){
+ if(data) {
CFSocketNativeHandle fd;
CFDataGetBytes(data, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8*) &fd);
CFRelease(data);
sock = (transport_socket_xt *) getSocket(context, fd);
- } else if (eventType == kCFStreamEventErrorOccurred) { // this event returns null data
+ }
+ else if (eventType == kCFStreamEventErrorOccurred) { // this event returns null data
sock = (transport_socket_xt *) getSocketByStream(context, stream);
}
-
+
if(!sock) {
goto bail;
}
-
+
switch(eventType) {
- case kCFStreamEventOpenCompleted:
- {
- TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> kCFStreamEventOpenCompleted(fd=%d)", sock->fd);
+ case kCFStreamEventOpenCompleted: {
+ TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> kCFStreamEventOpenCompleted(fd=%d)", sock->fd);
#if 0
- // Check SSL certificates
- if (TNET_SOCKET_TYPE_IS_TLS(sock->type) && transport->tls.verify) {
- if (!isTrusted(transport, (__bridge id)stream, YES/*YES read stream*/)) {
- TSK_DEBUG_ERROR("Remote SSL certs not trusted...closing the write stream");
- TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, sock->fd);
- removeSocket(sock, context);
- break;
- }
+ // Check SSL certificates
+ if (TNET_SOCKET_TYPE_IS_TLS(sock->type) && transport->tls.verify) {
+ if (!isTrusted(transport, (__bridge id)stream, YES/*YES read stream*/)) {
+ TSK_DEBUG_ERROR("Remote SSL certs not trusted...closing the write stream");
+ TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, sock->fd);
+ removeSocket(sock, context);
+ break;
}
+ }
#endif
- // Set "readable" flag
- if (!sock->readable) {
- sock->readable = tsk_true;
- if (sock->writable) {
- if (!sock->proxy_info || sock->proxy_handshacking_completed) {
- // no proxy or handshaking not done yet
- TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, sock->fd);
- }
- else if (sock->proxy_info && !sock->proxy_handshacking_started) {
- // proxy handshaking not done yet
- sock->proxy_handshacking_started = tsk_true;
- startProxyHandshaking(transport, sock);
- }
+ // Set "readable" flag
+ if (!sock->readable) {
+ sock->readable = tsk_true;
+ if (sock->writable) {
+ if (!sock->proxy_info || sock->proxy_handshacking_completed) {
+ // no proxy or handshaking not done yet
+ TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, sock->fd);
+ }
+ else if (sock->proxy_info && !sock->proxy_handshacking_started) {
+ // proxy handshaking not done yet
+ sock->proxy_handshacking_started = tsk_true;
+ startProxyHandshaking(transport, sock);
}
}
- break;
- }
- case kCFStreamEventEndEncountered:
- {
- TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> kCFStreamEventEndEncountered(fd=%d)", sock->fd);
- TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, sock->fd);
- removeSocket(sock, context);
- break;
- }
- case kCFStreamEventHasBytesAvailable:
- {
- recvData(transport, sock);
- break;
- }
- case kCFStreamEventErrorOccurred:
- {
- // Get the error code
- CFErrorRef error = CFReadStreamCopyError(stream);
- if (error) {
- TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> Error=%lu -> %s, fd=%d, status=%ld", CFErrorGetCode(error), CFStringGetCStringPtr(CFErrorGetDomain(error), kCFStringEncodingUTF8), sock->fd, CFReadStreamGetStatus(stream));
- CFRelease(error);
- }
-
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, sock->fd);
- removeSocket(sock, context);
- break;
}
- default:
- {
- // Not Implemented
- TSK_DEBUG_WARN("Not implemented");
- break;
+ break;
+ }
+ case kCFStreamEventEndEncountered: {
+ TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> kCFStreamEventEndEncountered(fd=%d)", sock->fd);
+ TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, sock->fd);
+ removeSocket(sock, context);
+ break;
+ }
+ case kCFStreamEventHasBytesAvailable: {
+ recvData(transport, sock);
+ break;
+ }
+ case kCFStreamEventErrorOccurred: {
+ // Get the error code
+ CFErrorRef error = CFReadStreamCopyError(stream);
+ if (error) {
+ TSK_DEBUG_INFO("__CFReadStreamClientCallBack --> Error=%lu -> %s, fd=%d, status=%ld", CFErrorGetCode(error), CFStringGetCStringPtr(CFErrorGetDomain(error), kCFStringEncodingUTF8), sock->fd, CFReadStreamGetStatus(stream));
+ CFRelease(error);
}
+
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, sock->fd);
+ removeSocket(sock, context);
+ break;
+ }
+ default: {
+ // Not Implemented
+ TSK_DEBUG_WARN("Not implemented");
+ break;
+ }
}
-
+
/* unlock context */
bail:
tsk_safeobj_unlock(context);
}
-void __CFWriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo) {
+void __CFWriteStreamClientCallBack(CFWriteStreamRef stream, CFStreamEventType eventType, void *clientCallBackInfo)
+{
// Extract the context
tnet_transport_t *transport = (tnet_transport_t *) clientCallBackInfo;
transport_context_t *context = transport->context;
-
+
/* lock context */
tsk_safeobj_lock(context);
-
+
// Extract the native socket
CFDataRef data = CFWriteStreamCopyProperty(stream, kCFStreamPropertySocketNativeHandle);
transport_socket_xt *sock = tsk_null;
- if(data){
+ if(data) {
CFSocketNativeHandle fd;
CFDataGetBytes(data, CFRangeMake(0, sizeof(CFSocketNativeHandle)), (UInt8*) &fd);
CFRelease(data);
sock = (transport_socket_xt *) getSocket(context, fd);
- } else if (eventType == kCFStreamEventErrorOccurred) { // this event returns null data
+ }
+ else if (eventType == kCFStreamEventErrorOccurred) { // this event returns null data
sock = (transport_socket_xt *) getSocketByStream(context, stream);
}
-
+
if(!sock) {
goto bail;
}
-
+
switch(eventType) {
- case kCFStreamEventOpenCompleted:
- {
- TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> kCFStreamEventOpenCompleted(fd=%d)", sock->fd);
- // still not connected, see kCFStreamEventCanAcceptBytes
- break;
+ case kCFStreamEventOpenCompleted: {
+ TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> kCFStreamEventOpenCompleted(fd=%d)", sock->fd);
+ // still not connected, see kCFStreamEventCanAcceptBytes
+ break;
+ }
+ case kCFStreamEventCanAcceptBytes: {
+ // To avoid blocking, call this function only if CFWriteStreamCanAcceptBytes returns true or after the stream’s client (set with CFWriteStreamSetClient) is notified of a kCFStreamEventCanAcceptBytes event.
+ TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> kCFStreamEventCanAcceptBytes(fd=%d)", sock->fd);
+ // Check SSL certificates
+ if (TNET_SOCKET_TYPE_IS_TLS(sock->type) && transport->tls.verify) {
+ if (!isTrusted(transport, (__bridge id)stream, FALSE/*NOT read stream*/)) {
+ TSK_DEBUG_ERROR("Remote SSL certs not trusted...closing the write stream");
+ removeSocket(sock, context);
+ break;
+ }
}
- case kCFStreamEventCanAcceptBytes:
- {
- // To avoid blocking, call this function only if CFWriteStreamCanAcceptBytes returns true or after the stream’s client (set with CFWriteStreamSetClient) is notified of a kCFStreamEventCanAcceptBytes event.
- TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> kCFStreamEventCanAcceptBytes(fd=%d)", sock->fd);
- // Check SSL certificates
- if (TNET_SOCKET_TYPE_IS_TLS(sock->type) && transport->tls.verify) {
- if (!isTrusted(transport, (__bridge id)stream, FALSE/*NOT read stream*/)) {
- TSK_DEBUG_ERROR("Remote SSL certs not trusted...closing the write stream");
- removeSocket(sock, context);
- break;
+ // Set "writable" flag
+ if (!sock->writable) {
+ sock->writable = tsk_true;
+ if (sock->readable) {
+ if (!sock->proxy_info || sock->proxy_handshacking_completed) {
+ // no proxy or handshaking not done yet
+ TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, sock->fd);
}
- }
- // Set "writable" flag
- if (!sock->writable) {
- sock->writable = tsk_true;
- if (sock->readable) {
- if (!sock->proxy_info || sock->proxy_handshacking_completed) {
- // no proxy or handshaking not done yet
- TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, sock->fd);
- }
- else if (sock->proxy_info && !sock->proxy_handshacking_started) {
- // proxy handshaking not done yet
- sock->proxy_handshacking_started = tsk_true;
- startProxyHandshaking(transport, sock);
- }
+ else if (sock->proxy_info && !sock->proxy_handshacking_started) {
+ // proxy handshaking not done yet
+ sock->proxy_handshacking_started = tsk_true;
+ startProxyHandshaking(transport, sock);
}
}
- break;
- }
- case kCFStreamEventEndEncountered:
- {
- TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> kCFStreamEventEndEncountered(fd=%d)", sock->fd);
- TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, sock->fd);
- removeSocket(sock, context);
- break;
}
- case kCFStreamEventErrorOccurred:
- {
- // Get the error code
- CFErrorRef error = CFWriteStreamCopyError(stream);
- if (error) {
- TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> Error=%lu -> %s, fd=%d", CFErrorGetCode(error), CFStringGetCStringPtr(CFErrorGetDomain(error), kCFStringEncodingUTF8), sock->fd);
- CFRelease(error);
- }
-
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, sock->fd);
- removeSocket(sock, context);
- break;
- }
- default:
- {
- // Not Implemented
- TSK_DEBUG_ERROR("Not implemented");
- break;
+ break;
+ }
+ case kCFStreamEventEndEncountered: {
+ TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> kCFStreamEventEndEncountered(fd=%d)", sock->fd);
+ TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, sock->fd);
+ removeSocket(sock, context);
+ break;
+ }
+ case kCFStreamEventErrorOccurred: {
+ // Get the error code
+ CFErrorRef error = CFWriteStreamCopyError(stream);
+ if (error) {
+ TSK_DEBUG_INFO("__CFWriteStreamClientCallBack --> Error=%lu -> %s, fd=%d", CFErrorGetCode(error), CFStringGetCStringPtr(CFErrorGetDomain(error), kCFStringEncodingUTF8), sock->fd);
+ CFRelease(error);
}
+
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, sock->fd);
+ removeSocket(sock, context);
+ break;
+ }
+ default: {
+ // Not Implemented
+ TSK_DEBUG_ERROR("Not implemented");
+ break;
+ }
}
-
+
/* unlock context */
bail:
tsk_safeobj_unlock(context);
}
-void __CFSocketCallBack(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info) {
+void __CFSocketCallBack(CFSocketRef s, CFSocketCallBackType callbackType, CFDataRef address, const void *data, void *info)
+{
// Extract the context
tnet_transport_t *transport = (tnet_transport_t *) info;
transport_context_t *context = transport->context;
-
+
// Extract the native socket
int fd = CFSocketGetNative(s);
transport_socket_xt *sock = (transport_socket_xt *) getSocket(context, fd);
- if(!sock) goto bail;
-
+ if(!sock) {
+ goto bail;
+ }
+
/* lock context */
tsk_safeobj_lock(context);
-
+
switch (callbackType) {
- case kCFSocketReadCallBack:
- {
- recvData(transport, sock);
- break;
- }
- case kCFSocketAcceptCallBack:
- case kCFSocketConnectCallBack:
- case kCFSocketWriteCallBack:
- {
- TSK_DEBUG_INFO("__CFSocketCallBack(fd=%d), callbackType=%lu", sock->fd, callbackType);
- wrapSocket(transport, sock);
- break;
- }
- case kCFSocketDataCallBack:
- {
- if (data) {
- const UInt8 *ptr = CFDataGetBytePtr((CFDataRef)data);
- int len = (int)CFDataGetLength((CFDataRef)data);
- if (ptr && len > 0) {
- tnet_transport_event_t* e = tnet_transport_event_create(event_data, transport->callback_data, sock->fd);
- if (e) {
- e->data = tsk_malloc(len);
- if (e->data) {
- memcpy(e->data, ptr, len);
- e->size = len;
- }
- struct sockaddr* address_ = (struct sockaddr*)CFDataGetBytePtr(address);
- memcpy(&e->remote_addr, address_, tnet_get_sockaddr_size(address_));
- TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
+ case kCFSocketReadCallBack: {
+ recvData(transport, sock);
+ break;
+ }
+ case kCFSocketAcceptCallBack:
+ case kCFSocketConnectCallBack:
+ case kCFSocketWriteCallBack: {
+ TSK_DEBUG_INFO("__CFSocketCallBack(fd=%d), callbackType=%lu", sock->fd, callbackType);
+ wrapSocket(transport, sock);
+ break;
+ }
+ case kCFSocketDataCallBack: {
+ if (data) {
+ const UInt8 *ptr = CFDataGetBytePtr((CFDataRef)data);
+ int len = (int)CFDataGetLength((CFDataRef)data);
+ if (ptr && len > 0) {
+ tnet_transport_event_t* e = tnet_transport_event_create(event_data, transport->callback_data, sock->fd);
+ if (e) {
+ e->data = tsk_malloc(len);
+ if (e->data) {
+ memcpy(e->data, ptr, len);
+ e->size = len;
}
+ struct sockaddr* address_ = (struct sockaddr*)CFDataGetBytePtr(address);
+ memcpy(&e->remote_addr, address_, tnet_get_sockaddr_size(address_));
+ TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
}
}
- break;
- }
-
- default:
- {
- // Not Implemented
- TSK_DEBUG_ERROR("Not implemented");
- break;
}
+ break;
}
-
+
+ default: {
+ // Not Implemented
+ TSK_DEBUG_ERROR("Not implemented");
+ break;
+ }
+ }
+
/* unlock context */
bail:
tsk_safeobj_unlock(context);
@@ -1076,52 +1072,53 @@ int wrapSocket(tnet_transport_t *transport, transport_socket_xt *sock)
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
// If the socket is already wrapped in a CFSocket or mainthead not started yet then return
if (!context->cf_run_loop) {
return 0;
}
-
+
// Put a reference to the transport context
const CFSocketContext socket_context = { 0, transport, NULL, NULL, NULL };
-
+
// Wrap socket and listen to events
if (!sock->cf_socket && !sock->cf_read_stream && !sock->cf_write_stream) {
sock->cf_socket = CFSocketCreateWithNative(kCFAllocatorDefault,
- sock->fd,
- kCFSocketReadCallBack | kCFSocketConnectCallBack | kCFSocketWriteCallBack | kCFSocketAcceptCallBack | kCFSocketDataCallBack,
- &__CFSocketCallBack,
- &socket_context);
-
+ sock->fd,
+ kCFSocketReadCallBack | kCFSocketConnectCallBack | kCFSocketWriteCallBack | kCFSocketAcceptCallBack | kCFSocketDataCallBack,
+ &__CFSocketCallBack,
+ &socket_context);
+
// Don't close the socket if the CFSocket is invalidated
CFOptionFlags flags = CFSocketGetSocketFlags(sock->cf_socket);
flags = flags & ~kCFSocketCloseOnInvalidate;
CFSocketSetSocketFlags(sock->cf_socket, flags);
-
+
// Create a new RunLoopSource and register it with the main thread RunLoop
sock->cf_run_loop_source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, sock->cf_socket, 0);
CFRunLoopAddSource(context->cf_run_loop, sock->cf_run_loop_source, kCFRunLoopCommonModes);
}
-
+
if (TNET_SOCKET_TYPE_IS_DGRAM(sock->type)) {
// Nothing to do
-
- } else if (TNET_SOCKET_TYPE_IS_STREAM(sock->type)) {
+
+ }
+ else if (TNET_SOCKET_TYPE_IS_STREAM(sock->type)) {
if (!sock->cf_read_stream && !sock->cf_write_stream) {
// Create a pair of streams (read/write) from the socket
CFStreamCreatePairWithSocket(kCFAllocatorDefault, sock->fd, &sock->cf_read_stream, &sock->cf_write_stream);
-
+
// Don't close underlying socket
CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse);
CFWriteStreamSetProperty(sock->cf_write_stream, kCFStreamPropertyShouldCloseNativeSocket, kCFBooleanFalse);
-
+
// Mark the stream for VoIP usage
CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty(sock->cf_write_stream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
-
+
// Setup a context for the streams
CFStreamClientContext streamContext = { 0, transport, NULL, NULL, NULL };
-
+
// Set the client callback for the stream
CFReadStreamSetClient(sock->cf_read_stream,
kCFStreamEventOpenCompleted | kCFStreamEventHasBytesAvailable | kCFStreamEventErrorOccurred | kCFStreamEventEndEncountered,
@@ -1131,18 +1128,18 @@ int wrapSocket(tnet_transport_t *transport, transport_socket_xt *sock)
kCFStreamEventOpenCompleted | kCFStreamEventErrorOccurred | kCFStreamEventCanAcceptBytes |kCFStreamEventEndEncountered,
&__CFWriteStreamClientCallBack,
&streamContext);
-
+
if (TNET_SOCKET_TYPE_IS_TLS(sock->type)) {
if ((ret = enableSSL(transport, sock)) != 0) {
return ret;
}
}
-
+
// Enroll streams in the run-loop
CFReadStreamScheduleWithRunLoop(sock->cf_read_stream, context->cf_run_loop, kCFRunLoopCommonModes);
CFWriteStreamScheduleWithRunLoop(sock->cf_write_stream, context->cf_run_loop, kCFRunLoopCommonModes);
}
-
+
// Open streams only if ready (otherwise, fails on iOS8)
if (tnet_sockfd_waitUntilReadable(sock->fd, 1) == 0 || tnet_sockfd_waitUntilWritable(sock->fd, 1) == 0) {
// switch from cf_socket to streams
@@ -1155,11 +1152,11 @@ int wrapSocket(tnet_transport_t *transport, transport_socket_xt *sock)
CFRelease(sock->cf_socket);
sock->cf_socket = NULL;
}
-
+
should_open_streams = tsk_true;
}
}
-
+
// Proxy
if (sock->proxy_info) {
if (sock->proxy_node && sock->proxy_node->type != sock->proxy_info->type) {
@@ -1178,7 +1175,7 @@ int wrapSocket(tnet_transport_t *transport, transport_socket_xt *sock)
TNET_PROXY_SET_SOCKET(sock->fd, sock->type),
TNET_PROXY_NODE_SET_NULL());
}
-
+
// Open streams
if (should_open_streams) {
if (!CFReadStreamOpen(sock->cf_read_stream)) {
@@ -1198,7 +1195,7 @@ int wrapSocket(tnet_transport_t *transport, transport_socket_xt *sock)
TSK_DEBUG_INFO("CFWriteStreamOpen(fd=%d) returned with status=%ld", sock->fd, status);
}
}
-
+
return 0;
}
@@ -1213,7 +1210,7 @@ static int enableSSL(tnet_transport_t *transport, transport_socket_xt *sock)
CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamPropertySocketSecurityLevel, kCFStreamSocketSecurityLevelNegotiatedSSL);
CFWriteStreamSetProperty(sock->cf_write_stream, kCFStreamSSLLevel, kCFStreamSocketSecurityLevelNegotiatedSSL);
CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamSSLLevel, kCFStreamSocketSecurityLevelNegotiatedSSL);
-
+
CFMutableDictionaryRef settings = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
#if (__IPHONE_OS_VERSION_MIN_REQUIRED < 40000) // @Deprecated
CFDictionaryAddValue(settings, kCFStreamSSLAllowsExpiredCertificates, kCFBooleanTrue);
@@ -1223,11 +1220,11 @@ static int enableSSL(tnet_transport_t *transport, transport_socket_xt *sock)
CFDictionaryAddValue(settings, kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
CFDictionaryAddValue(settings, kCFStreamSSLIsServer, sock->is_client ? kCFBooleanFalse : kCFBooleanTrue);
CFDictionaryAddValue(settings, kCFStreamSSLPeerName, kCFNull);
-
+
// Set the SSL settings
CFReadStreamSetProperty(sock->cf_read_stream, kCFStreamPropertySSLSettings, settings);
CFWriteStreamSetProperty(sock->cf_write_stream, kCFStreamPropertySSLSettings, settings);
-
+
CFRelease(settings);
}
return 0;
@@ -1239,12 +1236,12 @@ static int startProxyHandshaking(tnet_transport_t *transport, transport_socket_x
int ret;
void* handshaking_data_ptr = tsk_null;
tsk_size_t handshaking_data_size = 0;
-
+
if (!transport || !(context = transport->context) || !sock || !sock->proxy_info || !sock->proxy_node) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
-
+
// start handshaking
if ((ret = tnet_proxy_node_start_handshaking(sock->proxy_node)) != 0) {
return ret;
@@ -1260,7 +1257,7 @@ static int startProxyHandshaking(tnet_transport_t *transport, transport_socket_x
TSK_FREE(handshaking_data_ptr);
// check if handshaking completed
tnet_proxy_node_get_handshaking_completed(sock->proxy_node, &sock->proxy_handshacking_completed);
-
+
return ret;
}
@@ -1270,15 +1267,15 @@ void *tnet_transport_mainthread(void *param)
tnet_transport_t *transport = param;
transport_context_t *context = transport->context;
int i;
-
+
/* check whether the transport is already prepared */
if (!transport->prepared) {
TSK_DEBUG_ERROR("Transport must be prepared before strating.");
goto bail;
}
-
+
TSK_DEBUG_INFO("Starting [%s] server with IP {%s} on port {%d} with fd {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->fd);
-
+
// Set the RunLoop of the context
context->cf_run_loop = CFRunLoopGetCurrent();
CFRetain(context->cf_run_loop);
@@ -1288,22 +1285,22 @@ void *tnet_transport_mainthread(void *param)
wrapSocket(transport, context->sockets[i]);
}
tsk_safeobj_unlock(context);
-
+
while(TSK_RUNNABLE(transport)->running) {
// Give some time to process sources
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1.0, false);
-
+
if (!TSK_RUNNABLE(transport)->running) {
goto bail;
}
}
-
+
// Remove all the sockets, streams and sources from the run loop
tsk_safeobj_lock(context);
for(i = 0; i < context->count; i++) {
transport_context_t *context = transport->context;
transport_socket_xt *sock = context->sockets[i];
-
+
if (!sock) {
continue;
}
@@ -1320,11 +1317,11 @@ void *tnet_transport_mainthread(void *param)
}
}
tsk_safeobj_unlock(context);
-
-
+
+
bail:
TSK_DEBUG_INFO("Stopped [%s] server with IP {%s} on port {%d}...", transport->description, transport->master->ip, transport->master->port);
- if(context->cf_run_loop){
+ if(context->cf_run_loop) {
CFRelease(context->cf_run_loop);
context->cf_run_loop = NULL;
}
@@ -1357,7 +1354,7 @@ static tsk_object_t* transport_context_ctor(tsk_object_t * self, va_list * app)
}
static tsk_object_t* transport_context_dtor(tsk_object_t * self)
-{
+{
transport_context_t *context = self;
if (context) {
while(context->count) {
@@ -1368,12 +1365,11 @@ static tsk_object_t* transport_context_dtor(tsk_object_t * self)
return self;
}
-static const tsk_object_def_t tnet_transport_context_def_s =
-{
+static const tsk_object_def_t tnet_transport_context_def_s = {
sizeof(transport_context_t),
- transport_context_ctor,
+ transport_context_ctor,
transport_context_dtor,
- tsk_null,
+ tsk_null,
};
const tsk_object_def_t *tnet_transport_context_def_t = &tnet_transport_context_def_s;
diff --git a/tinyNET/src/tnet_transport_poll.c b/tinyNET/src/tnet_transport_poll.c
index 0774823..3aa8913 100755
--- a/tinyNET/src/tnet_transport_poll.c
+++ b/tinyNET/src/tnet_transport_poll.c
@@ -1,19 +1,19 @@
/*
* Copyright (C) 2010-2011 Mamadou Diop
* Copyright (C) 2012-2013 Doubango Telecom <http://www.doubango.org>
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -51,31 +51,29 @@
#endif
/*== Socket description ==*/
-typedef struct transport_socket_xs
-{
- tnet_fd_t fd;
- tsk_bool_t owner;
- tsk_bool_t connected;
- tsk_bool_t paused;
+typedef struct transport_socket_xs {
+ tnet_fd_t fd;
+ tsk_bool_t owner;
+ tsk_bool_t connected;
+ tsk_bool_t paused;
- tnet_socket_type_t type;
- tnet_tls_socket_handle_t* tlshandle;
+ tnet_socket_type_t type;
+ tnet_tls_socket_handle_t* tlshandle;
}
transport_socket_xt;
/*== Transport context structure definition ==*/
-typedef struct transport_context_s
-{
- TSK_DECLARE_OBJECT;
-
- tsk_size_t count;
- tnet_fd_t pipeW;
- tnet_fd_t pipeR;
- tnet_pollfd_t ufds[TNET_MAX_FDS];
- transport_socket_xt* sockets[TNET_MAX_FDS];
- tsk_bool_t polling; // whether we are poll()ing
-
- TSK_DECLARE_SAFEOBJ;
+typedef struct transport_context_s {
+ TSK_DECLARE_OBJECT;
+
+ tsk_size_t count;
+ tnet_fd_t pipeW;
+ tnet_fd_t pipeR;
+ tnet_pollfd_t ufds[TNET_MAX_FDS];
+ transport_socket_xt* sockets[TNET_MAX_FDS];
+ tsk_bool_t polling; // whether we are poll()ing
+
+ TSK_DECLARE_SAFEOBJ;
}
transport_context_t;
@@ -95,269 +93,270 @@ int tnet_transport_add_socket_2(const tnet_transport_handle_t *handle, tnet_fd_t
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- transport_context_t* context;
- static char c = '\0';
- int ret = -1;
-
- if(!transport){
- TSK_DEBUG_ERROR("Invalid server handle.");
- return ret;
- }
-
- if(!(context = (transport_context_t*)transport->context)){
- TSK_DEBUG_ERROR("Invalid context.");
- return -2;
- }
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ transport_context_t* context;
+ static char c = '\0';
+ int ret = -1;
+
+ if(!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ return ret;
+ }
- if(TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)){
- transport->tls.enabled = 1;
- }
-
- if((ret = addSocket(fd, type, transport, take_ownership, isClient, tlsHandle))){
- TSK_DEBUG_ERROR("Failed to add new Socket.");
- return ret;
- }
+ if(!(context = (transport_context_t*)transport->context)) {
+ TSK_DEBUG_ERROR("Invalid context.");
+ return -2;
+ }
- // signal
- if(context->pipeW && (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started)){
- if((ret = write(context->pipeW, &c, 1)) > 0){
- TSK_DEBUG_INFO("Socket added (external call) %d", fd);
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("Failed to add new Socket.");
- return ret;
- }
- } else {
- TSK_DEBUG_INFO("pipeW (write site) not initialized yet.");
- return 0; //Will be taken when mainthead start
- }
+ if(TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)) {
+ transport->tls.enabled = 1;
+ }
+
+ if((ret = addSocket(fd, type, transport, take_ownership, isClient, tlsHandle))) {
+ TSK_DEBUG_ERROR("Failed to add new Socket.");
+ return ret;
+ }
+
+ // signal
+ if(context->pipeW && (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started)) {
+ if((ret = write(context->pipeW, &c, 1)) > 0) {
+ TSK_DEBUG_INFO("Socket added (external call) %d", fd);
+ return 0;
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to add new Socket.");
+ return ret;
+ }
+ }
+ else {
+ TSK_DEBUG_INFO("pipeW (write site) not initialized yet.");
+ return 0; //Will be taken when mainthead start
+ }
}
int tnet_transport_pause_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tsk_bool_t pause)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- transport_context_t *context;
- transport_socket_xt* socket;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ transport_context_t *context;
+ transport_socket_xt* socket;
- if(!transport || !(context = (transport_context_t*)transport->context)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if(!transport || !(context = (transport_context_t*)transport->context)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- if((socket = getSocket(context, fd))){
- socket->paused = pause;
- }
- else{
- TSK_DEBUG_WARN("Socket does not exist in this context");
- }
- return 0;
+ if((socket = getSocket(context, fd))) {
+ socket->paused = pause;
+ }
+ else {
+ TSK_DEBUG_WARN("Socket does not exist in this context");
+ }
+ return 0;
}
/* Remove socket */
int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_t *pfd)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- transport_context_t *context;
- int ret = -1;
- tsk_size_t i;
- tsk_bool_t found = tsk_false;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ transport_context_t *context;
+ int ret = -1;
+ tsk_size_t i;
+ tsk_bool_t found = tsk_false;
tnet_fd_t fd = *pfd;
-
- TSK_DEBUG_INFO("Removing socket %d", fd);
- if(!transport){
- TSK_DEBUG_ERROR("Invalid server handle.");
- return ret;
- }
-
- if(!(context = (transport_context_t*)transport->context)){
- TSK_DEBUG_ERROR("Invalid context.");
- return -2;
- }
-
- tsk_safeobj_lock(context);
+ TSK_DEBUG_INFO("Removing socket %d", fd);
- for(i=0; i<context->count; i++){
- if(context->sockets[i]->fd == fd){
- tsk_bool_t self_ref = (&context->sockets[i]->fd == pfd);
- removeSocket(i, context); // sockets[i] will be destroyed
- found = tsk_true;
- TSK_RUNNABLE_ENQUEUE(transport, event_removed, transport->callback_data, fd);
- if(!self_ref){ // if self_ref then, pfd no longer valid after removeSocket()
- *pfd = TNET_INVALID_FD;
- }
- break;
- }
- }
+ if(!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ return ret;
+ }
- tsk_safeobj_unlock(context);
-
- if(found){
- /* Signal */
- static char c = '\0';
- ret = write(context->pipeW, &c, 1);
- return (ret > 0 ? 0 : ret);
- }
-
- // ...
-
- return -1;
+ if(!(context = (transport_context_t*)transport->context)) {
+ TSK_DEBUG_ERROR("Invalid context.");
+ return -2;
+ }
+
+ tsk_safeobj_lock(context);
+
+ for(i=0; i<context->count; i++) {
+ if(context->sockets[i]->fd == fd) {
+ tsk_bool_t self_ref = (&context->sockets[i]->fd == pfd);
+ removeSocket(i, context); // sockets[i] will be destroyed
+ found = tsk_true;
+ TSK_RUNNABLE_ENQUEUE(transport, event_removed, transport->callback_data, fd);
+ if(!self_ref) { // if self_ref then, pfd no longer valid after removeSocket()
+ *pfd = TNET_INVALID_FD;
+ }
+ break;
+ }
+ }
+
+ tsk_safeobj_unlock(context);
+
+ if(found) {
+ /* Signal */
+ static char c = '\0';
+ ret = write(context->pipeW, &c, 1);
+ return (ret > 0 ? 0 : ret);
+ }
+
+ // ...
+
+ return -1;
}
tsk_size_t tnet_transport_send(const tnet_transport_handle_t *handle, tnet_fd_t from, const void* buf, tsk_size_t size)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- int numberOfBytesSent = 0;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ int numberOfBytesSent = 0;
- if(!transport){
- TSK_DEBUG_ERROR("Invalid transport handle.");
- goto bail;
- }
+ if(!transport) {
+ TSK_DEBUG_ERROR("Invalid transport handle.");
+ goto bail;
+ }
- if(transport->tls.enabled){
- const transport_socket_xt* socket = getSocket(transport->context, from);
- if(socket && socket->tlshandle){
- if(!tnet_tls_socket_send(socket->tlshandle, buf, size)){
- numberOfBytesSent = size;
- }
- else{
- numberOfBytesSent = 0;
- }
- goto bail;
- }
- }
- else if((numberOfBytesSent = tnet_sockfd_send(from, buf, size, 0)) <= 0){
- TNET_PRINT_LAST_ERROR("send have failed.");
+ if(transport->tls.enabled) {
+ const transport_socket_xt* socket = getSocket(transport->context, from);
+ if(socket && socket->tlshandle) {
+ if(!tnet_tls_socket_send(socket->tlshandle, buf, size)) {
+ numberOfBytesSent = size;
+ }
+ else {
+ numberOfBytesSent = 0;
+ }
+ goto bail;
+ }
+ }
+ else if((numberOfBytesSent = tnet_sockfd_send(from, buf, size, 0)) <= 0) {
+ TNET_PRINT_LAST_ERROR("send have failed.");
- //tnet_sockfd_close(&from);
- goto bail;
- }
+ //tnet_sockfd_close(&from);
+ goto bail;
+ }
bail:
transport->bytes_out += numberOfBytesSent;
- return numberOfBytesSent;
+ return numberOfBytesSent;
}
tsk_size_t tnet_transport_sendto(const tnet_transport_handle_t *handle, tnet_fd_t from, const struct sockaddr *to, const void* buf, tsk_size_t size)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- int numberOfBytesSent = 0;
-
- if(!transport){
- TSK_DEBUG_ERROR("Invalid server handle.");
- goto bail;
- }
-
- if(!TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)){
- TSK_DEBUG_ERROR("In order to use sendto() you must use an udp transport.");
- goto bail;
- }
-
- if((numberOfBytesSent = tnet_sockfd_sendto(from, to, buf, size)) <= 0){
- TNET_PRINT_LAST_ERROR("sendto have failed.");
- goto bail;
- }
-
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ int numberOfBytesSent = 0;
+
+ if(!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ goto bail;
+ }
+
+ if(!TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)) {
+ TSK_DEBUG_ERROR("In order to use sendto() you must use an udp transport.");
+ goto bail;
+ }
+
+ if((numberOfBytesSent = tnet_sockfd_sendto(from, to, buf, size)) <= 0) {
+ TNET_PRINT_LAST_ERROR("sendto have failed.");
+ goto bail;
+ }
+
bail:
transport->bytes_out += numberOfBytesSent;
- return numberOfBytesSent;
+ return numberOfBytesSent;
}
int tnet_transport_have_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
-
- if(!transport){
- TSK_DEBUG_ERROR("Invalid server handle.");
- return 0;
- }
-
- return (getSocket((transport_context_t*)transport->context, fd) != 0);
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+
+ if(!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ return 0;
+ }
+
+ return (getSocket((transport_context_t*)transport->context, fd) != 0);
}
const tnet_tls_socket_handle_t* tnet_transport_get_tlshandle(const tnet_transport_handle_t *handle, tnet_fd_t fd)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- const transport_socket_xt *socket;
-
- if(!transport){
- TSK_DEBUG_ERROR("Invalid parameter");
- return 0;
- }
-
- if((socket = getSocket((transport_context_t*)transport->context, fd))){
- return socket->tlshandle;
- }
- return 0;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ const transport_socket_xt *socket;
+
+ if(!transport) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return 0;
+ }
+
+ if((socket = getSocket((transport_context_t*)transport->context, fd))) {
+ return socket->tlshandle;
+ }
+ return 0;
}
/*== Get socket ==*/
static transport_socket_xt* getSocket(transport_context_t *context, tnet_fd_t fd)
{
- tsk_size_t i;
- transport_socket_xt* ret = 0;
-
- if(context){
- tsk_safeobj_lock(context);
- for(i=0; i<context->count; i++){
- if(context->sockets[i]->fd == fd){
- ret = context->sockets[i];
- break;
- }
- }
- tsk_safeobj_unlock(context);
- }
-
- return ret;
+ tsk_size_t i;
+ transport_socket_xt* ret = 0;
+
+ if(context) {
+ tsk_safeobj_lock(context);
+ for(i=0; i<context->count; i++) {
+ if(context->sockets[i]->fd == fd) {
+ ret = context->sockets[i];
+ break;
+ }
+ }
+ tsk_safeobj_unlock(context);
+ }
+
+ return ret;
}
/*== Add new socket ==*/
int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client, tnet_tls_socket_handle_t* tlsHandle)
{
- transport_context_t *context = transport?transport->context:0;
- if(context){
- transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
- sock->fd = fd;
- sock->type = type;
- sock->owner = take_ownership;
-
- if((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled){
- if(tlsHandle){
- sock->tlshandle = tsk_object_ref(tlsHandle);
- }
- else{
+ transport_context_t *context = transport?transport->context:0;
+ if(context) {
+ transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
+ sock->fd = fd;
+ sock->type = type;
+ sock->owner = take_ownership;
+
+ if((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled) {
+ if(tlsHandle) {
+ sock->tlshandle = tsk_object_ref(tlsHandle);
+ }
+ else {
#if HAVE_OPENSSL
- sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
+ sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
#endif
- }
- }
-
- tsk_safeobj_lock(context);
-
- context->ufds[context->count].fd = fd;
- context->ufds[context->count].events = (fd == context->pipeR) ? TNET_POLLIN : (TNET_POLLIN | TNET_POLLNVAL | TNET_POLLERR);
- if(TNET_SOCKET_TYPE_IS_STREAM(sock->type) && fd != context->pipeR){
- context->ufds[context->count].events |= TNET_POLLOUT; // emulate WinSock2 FD_CONNECT event
- }
- context->ufds[context->count].revents = 0;
- context->sockets[context->count] = sock;
-
- context->count++;
-
- tsk_safeobj_unlock(context);
-
- TSK_DEBUG_INFO("Socket added[%s]: fd=%d, tail.count=%d", transport->description, fd, (int)context->count);
-
- return 0;
- }
- else{
- TSK_DEBUG_ERROR("Context is Null.");
- return -1;
- }
+ }
+ }
+
+ tsk_safeobj_lock(context);
+
+ context->ufds[context->count].fd = fd;
+ context->ufds[context->count].events = (fd == context->pipeR) ? TNET_POLLIN : (TNET_POLLIN | TNET_POLLNVAL | TNET_POLLERR);
+ if(TNET_SOCKET_TYPE_IS_STREAM(sock->type) && fd != context->pipeR) {
+ context->ufds[context->count].events |= TNET_POLLOUT; // emulate WinSock2 FD_CONNECT event
+ }
+ context->ufds[context->count].revents = 0;
+ context->sockets[context->count] = sock;
+
+ context->count++;
+
+ tsk_safeobj_unlock(context);
+
+ TSK_DEBUG_INFO("Socket added[%s]: fd=%d, tail.count=%d", transport->description, fd, (int)context->count);
+
+ return 0;
+ }
+ else {
+ TSK_DEBUG_ERROR("Context is Null.");
+ return -1;
+ }
}
/*== change connection state ==*/
@@ -378,180 +377,180 @@ static void setConnected(tnet_fd_t fd, transport_context_t *context, int connect
/*== Remove socket ==*/
int removeSocket(int index, transport_context_t *context)
{
- int i;
-
- tsk_safeobj_lock(context);
-
- if(index < (int)context->count){
- /* Close the socket if we are the owner. */
- TSK_DEBUG_INFO("Socket to remove: fd=%d, index=%d, tail.count=%d", context->sockets[index]->fd, index, (int)context->count);
- if(context->sockets[index]->owner){
- // do not close the socket while it's being poll()ed
- // http://stackoverflow.com/questions/5039608/poll-cant-detect-event-when-socket-is-closed-locally
- if(context->polling){
- TSK_DEBUG_INFO("RemoveSocket(fd=%d) has been requested but we are poll()ing the socket. ShutdownSocket(fd) called on the socket and we deferred the request.", context->sockets[index]->fd);
- TSK_DEBUG_INFO("ShutdownSocket(fd=%d)", context->sockets[index]->fd);
- tnet_sockfd_shutdown(context->sockets[index]->fd);
- goto done;
- }
- tnet_sockfd_close(&(context->sockets[index]->fd));
- }
-
- /* Free tls context */
- TSK_OBJECT_SAFE_FREE(context->sockets[index]->tlshandle);
-
- // Free socket
- TSK_FREE(context->sockets[index]);
-
- for(i=index ; i<context->count-1; i++){
- context->sockets[i] = context->sockets[i+1];
- context->ufds[i] = context->ufds[i+1];
- }
-
- context->sockets[context->count-1] = tsk_null;
- context->ufds[context->count-1].fd = TNET_INVALID_FD;
- context->ufds[context->count-1].events = 0;
- context->ufds[context->count-1].revents = 0;
-
- context->count--;
- }
+ int i;
+
+ tsk_safeobj_lock(context);
+
+ if(index < (int)context->count) {
+ /* Close the socket if we are the owner. */
+ TSK_DEBUG_INFO("Socket to remove: fd=%d, index=%d, tail.count=%d", context->sockets[index]->fd, index, (int)context->count);
+ if(context->sockets[index]->owner) {
+ // do not close the socket while it's being poll()ed
+ // http://stackoverflow.com/questions/5039608/poll-cant-detect-event-when-socket-is-closed-locally
+ if(context->polling) {
+ TSK_DEBUG_INFO("RemoveSocket(fd=%d) has been requested but we are poll()ing the socket. ShutdownSocket(fd) called on the socket and we deferred the request.", context->sockets[index]->fd);
+ TSK_DEBUG_INFO("ShutdownSocket(fd=%d)", context->sockets[index]->fd);
+ tnet_sockfd_shutdown(context->sockets[index]->fd);
+ goto done;
+ }
+ tnet_sockfd_close(&(context->sockets[index]->fd));
+ }
+
+ /* Free tls context */
+ TSK_OBJECT_SAFE_FREE(context->sockets[index]->tlshandle);
+
+ // Free socket
+ TSK_FREE(context->sockets[index]);
+
+ for(i=index ; i<context->count-1; i++) {
+ context->sockets[i] = context->sockets[i+1];
+ context->ufds[i] = context->ufds[i+1];
+ }
+
+ context->sockets[context->count-1] = tsk_null;
+ context->ufds[context->count-1].fd = TNET_INVALID_FD;
+ context->ufds[context->count-1].events = 0;
+ context->ufds[context->count-1].revents = 0;
+
+ context->count--;
+ }
done:
- tsk_safeobj_unlock(context);
-
- return 0;
+ tsk_safeobj_unlock(context);
+
+ return 0;
}
int tnet_transport_stop(tnet_transport_t *transport)
-{
- int ret;
- transport_context_t *context;
+{
+ int ret;
+ transport_context_t *context;
- if(!transport){
- return -1;
- }
-
- context = transport->context;
+ if(!transport) {
+ return -1;
+ }
- if((ret = tsk_runnable_stop(TSK_RUNNABLE(transport)))){
- return ret;
- }
-
- if(context){
- static char c = '\0';
-
- // signal
- tsk_safeobj_lock(context); // =>MUST
- if(tnet_transport_have_socket(transport, context->pipeR)){ // to avoid SIGPIPE=> check that there is at least one reader
- write(context->pipeW, &c, 1);
- }
- tsk_safeobj_unlock(context);
- }
-
- if(transport->mainThreadId[0]){
- return tsk_thread_join(transport->mainThreadId);
- }
- else{
- /* already soppped */
- return 0;
- }
+ context = transport->context;
+
+ if((ret = tsk_runnable_stop(TSK_RUNNABLE(transport)))) {
+ return ret;
+ }
+
+ if(context) {
+ static char c = '\0';
+
+ // signal
+ tsk_safeobj_lock(context); // =>MUST
+ if(tnet_transport_have_socket(transport, context->pipeR)) { // to avoid SIGPIPE=> check that there is at least one reader
+ write(context->pipeW, &c, 1);
+ }
+ tsk_safeobj_unlock(context);
+ }
+
+ if(transport->mainThreadId[0]) {
+ return tsk_thread_join(transport->mainThreadId);
+ }
+ else {
+ /* already soppped */
+ return 0;
+ }
}
int tnet_transport_prepare(tnet_transport_t *transport)
{
- int ret = -1;
- transport_context_t *context;
- tnet_fd_t pipes[2];
-
- TSK_DEBUG_INFO("tnet_transport_prepare()");
-
- if(!transport || !transport->context){
- TSK_DEBUG_ERROR("Invalid parameter.");
- return -1;
- }
- else{
- context = transport->context;
- }
-
- if(transport->prepared){
- TSK_DEBUG_ERROR("Transport already prepared.");
- return -2;
- }
+ int ret = -1;
+ transport_context_t *context;
+ tnet_fd_t pipes[2];
+
+ TSK_DEBUG_INFO("tnet_transport_prepare()");
+
+ if(!transport || !transport->context) {
+ TSK_DEBUG_ERROR("Invalid parameter.");
+ return -1;
+ }
+ else {
+ context = transport->context;
+ }
+
+ if(transport->prepared) {
+ TSK_DEBUG_ERROR("Transport already prepared.");
+ return -2;
+ }
+
+ /* Prepare master */
+ if(!transport->master) {
+ if((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))) {
+ tsk_strupdate(&transport->local_ip, transport->master->ip);
+ transport->bind_local_port = transport->master->port;
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to create master socket");
+ return -3;
+ }
+ }
+
+ /* Start listening */
+ if(TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
+ if((ret = tnet_sockfd_listen(transport->master->fd, TNET_MAX_FDS))) {
+ TNET_PRINT_LAST_ERROR("listen have failed.");
+ goto bail;
+ }
+ }
+
+ /* Create and add pipes to the fd_set */
+ if((ret = pipe(pipes))) {
+ TNET_PRINT_LAST_ERROR("Failed to create new pipes.");
+ goto bail;
+ }
+
+ /* set both R and W sides */
+ context->pipeR = pipes[0];
+ context->pipeW = pipes[1];
+
+ /* add R side */
+ TSK_DEBUG_INFO("pipeR fd=%d, pipeW=%d", context->pipeR, context->pipeW);
+ if((ret = addSocket(context->pipeR, transport->master->type, transport, tsk_true, tsk_false, tsk_null))) {
+ goto bail;
+ }
+
+ /* Add the master socket to the context. */
+ TSK_DEBUG_INFO("master fd=%d", transport->master->fd);
+ // don't take ownership: will be closed by the dctor() when refCount==0
+ // otherwise will be closed twice: dctor() and removeSocket()
+ if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false, tsk_null))) {
+ TSK_DEBUG_ERROR("Failed to add master socket");
+ goto bail;
+ }
+
+ transport->prepared = tsk_true;
- /* Prepare master */
- if(!transport->master){
- if((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))){
- tsk_strupdate(&transport->local_ip, transport->master->ip);
- transport->bind_local_port = transport->master->port;
- }
- else{
- TSK_DEBUG_ERROR("Failed to create master socket");
- return -3;
- }
- }
-
- /* Start listening */
- if(TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)){
- if((ret = tnet_sockfd_listen(transport->master->fd, TNET_MAX_FDS))){
- TNET_PRINT_LAST_ERROR("listen have failed.");
- goto bail;
- }
- }
-
- /* Create and add pipes to the fd_set */
- if((ret = pipe(pipes))){
- TNET_PRINT_LAST_ERROR("Failed to create new pipes.");
- goto bail;
- }
-
- /* set both R and W sides */
- context->pipeR = pipes[0];
- context->pipeW = pipes[1];
-
- /* add R side */
- TSK_DEBUG_INFO("pipeR fd=%d, pipeW=%d", context->pipeR, context->pipeW);
- if((ret = addSocket(context->pipeR, transport->master->type, transport, tsk_true, tsk_false, tsk_null))){
- goto bail;
- }
-
- /* Add the master socket to the context. */
- TSK_DEBUG_INFO("master fd=%d", transport->master->fd);
- // don't take ownership: will be closed by the dctor() when refCount==0
- // otherwise will be closed twice: dctor() and removeSocket()
- if((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false, tsk_null))){
- TSK_DEBUG_ERROR("Failed to add master socket");
- goto bail;
- }
-
- transport->prepared = tsk_true;
-
bail:
- return ret;
+ return ret;
}
int tnet_transport_unprepare(tnet_transport_t *transport)
{
- //int ret = -1;
- transport_context_t *context;
-
- if(!transport || !transport->context){
- TSK_DEBUG_ERROR("Invalid parameter.");
- return -1;
- }
- else{
- context = transport->context;
- }
+ //int ret = -1;
+ transport_context_t *context;
- if(!transport->prepared){
- return 0;
- }
+ if(!transport || !transport->context) {
+ TSK_DEBUG_ERROR("Invalid parameter.");
+ return -1;
+ }
+ else {
+ context = transport->context;
+ }
- transport->prepared = tsk_false;
-
- while(context->count){
- removeSocket(0, context); // safe
- }
+ if(!transport->prepared) {
+ return 0;
+ }
- /* reset both R and W sides */
+ transport->prepared = tsk_false;
+
+ while(context->count) {
+ removeSocket(0, context); // safe
+ }
+
+ /* reset both R and W sides */
if (context->pipeW != -1) {
if (close(context->pipeW)) {
TSK_DEBUG_ERROR("Failed to close pipeW:%d", context->pipeW);
@@ -560,244 +559,242 @@ int tnet_transport_unprepare(tnet_transport_t *transport)
}
context->pipeR = -1;
- // destroy master as it has been closed by removeSocket()
- TSK_OBJECT_SAFE_FREE(transport->master);
+ // destroy master as it has been closed by removeSocket()
+ TSK_OBJECT_SAFE_FREE(transport->master);
- return 0;
+ return 0;
}
/*=== Main thread */
void *tnet_transport_mainthread(void *param)
{
- tnet_transport_t *transport = param;
- transport_context_t *context = transport->context;
- int ret, status;
- tsk_size_t i;
- tsk_bool_t is_stream;
+ tnet_transport_t *transport = param;
+ transport_context_t *context = transport->context;
+ int ret, status;
+ tsk_size_t i;
+ tsk_bool_t is_stream;
tnet_fd_t fd;
- struct sockaddr_storage remote_addr = {0};
- transport_socket_xt* active_socket;
+ struct sockaddr_storage remote_addr = {0};
+ transport_socket_xt* active_socket;
- /* check whether the transport is already prepared */
- if(!transport->prepared){
- TSK_DEBUG_ERROR("Transport must be prepared before strating.");
- goto bail;
- }
-
- is_stream = TNET_SOCKET_TYPE_IS_STREAM(transport->master->type);
-
- TSK_DEBUG_INFO("Starting [%s] server with IP {%s} on port {%d} using master fd {%d} with type {%d} with max_fds {%lu}...",
- transport->description,
- transport->master->ip,
- transport->master->port,
- transport->master->fd,
- transport->master->type,
- sizeof(context->ufds)/sizeof(context->ufds[0]));
-
- while(TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started){
- context->polling = tsk_true;
- ret = tnet_poll(context->ufds, context->count, -1);
- context->polling = tsk_false;
- if(ret < 0){
- TNET_PRINT_LAST_ERROR("poll() have failed.");
- goto bail;
- }
+ /* check whether the transport is already prepared */
+ if(!transport->prepared) {
+ TSK_DEBUG_ERROR("Transport must be prepared before strating.");
+ goto bail;
+ }
+
+ is_stream = TNET_SOCKET_TYPE_IS_STREAM(transport->master->type);
+
+ TSK_DEBUG_INFO("Starting [%s] server with IP {%s} on port {%d} using master fd {%d} with type {%d} with max_fds {%lu}...",
+ transport->description,
+ transport->master->ip,
+ transport->master->port,
+ transport->master->fd,
+ transport->master->type,
+ sizeof(context->ufds)/sizeof(context->ufds[0]));
+
+ while(TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started) {
+ context->polling = tsk_true;
+ ret = tnet_poll(context->ufds, context->count, -1);
+ context->polling = tsk_false;
+ if(ret < 0) {
+ TNET_PRINT_LAST_ERROR("poll() have failed.");
+ goto bail;
+ }
+
+ if(!TSK_RUNNABLE(transport)->running && !TSK_RUNNABLE(transport)->started) {
+ TSK_DEBUG_INFO("Stopping [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);
+ goto bail;
+ }
+
+ /* lock context */
+ tsk_safeobj_lock(context);
+
+ /* == == */
+ for(i=0; i<context->count; i++) {
+ if(!context->ufds[i].revents) {
+ continue;
+ }
+
+ // TSK_DEBUG_INFO("REVENTS(i=%d) = %d", i, context->ufds[i].revents);
+
+ if(context->ufds[i].fd == context->pipeR) {
+ TSK_DEBUG_INFO("PipeR event = %d", context->ufds[i].revents);
+ if(context->ufds[i].revents & TNET_POLLIN) {
+ static char __buffer[1024];
+ if(read(context->pipeR, __buffer, sizeof(__buffer)) < 0) {
+ TNET_PRINT_LAST_ERROR("Failed to read from the Pipe");
+ }
+ }
+ else if(context->ufds[i].revents & TNET_POLLHUP) {
+ TNET_PRINT_LAST_ERROR("Pipe Error");
+ goto bail;
+ }
+ context->ufds[i].revents = 0;
+ continue;
+ }
+
+ /* Get active event and socket */
+ active_socket = context->sockets[i];
- if(!TSK_RUNNABLE(transport)->running && !TSK_RUNNABLE(transport)->started){
- TSK_DEBUG_INFO("Stopping [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);
- goto bail;
- }
-
- /* lock context */
- tsk_safeobj_lock(context);
-
- /* == == */
- for(i=0; i<context->count; i++)
- {
- if(!context->ufds[i].revents){
- continue;
- }
-
- // TSK_DEBUG_INFO("REVENTS(i=%d) = %d", i, context->ufds[i].revents);
-
- if(context->ufds[i].fd == context->pipeR){
- TSK_DEBUG_INFO("PipeR event = %d", context->ufds[i].revents);
- if(context->ufds[i].revents & TNET_POLLIN){
- static char __buffer[1024];
- if(read(context->pipeR, __buffer, sizeof(__buffer)) < 0){
- TNET_PRINT_LAST_ERROR("Failed to read from the Pipe");
- }
- }
- else if(context->ufds[i].revents & TNET_POLLHUP){
- TNET_PRINT_LAST_ERROR("Pipe Error");
- goto bail;
- }
- context->ufds[i].revents = 0;
- continue;
- }
-
- /* Get active event and socket */
- active_socket = context->sockets[i];
-
/*================== TNET_POLLHUP ==================*/
- if(context->ufds[i].revents & (TNET_POLLHUP)){
- if(context->ufds[i].revents & TNET_POLLOUT){
- TSK_DEBUG_INFO("POLLOUT and POLLHUP are exclusive");
- }
- else{
- fd = active_socket->fd;
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLHUP(%d)", transport->description, fd);
-
- tnet_transport_remove_socket(transport, &active_socket->fd);
- TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
- continue;
- }
- }
-
- /*================== TNET_POLLERR ==================*/
- if(context->ufds[i].revents & (TNET_POLLERR)){
+ if(context->ufds[i].revents & (TNET_POLLHUP)) {
+ if(context->ufds[i].revents & TNET_POLLOUT) {
+ TSK_DEBUG_INFO("POLLOUT and POLLHUP are exclusive");
+ }
+ else {
+ fd = active_socket->fd;
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLHUP(%d)", transport->description, fd);
+
+ tnet_transport_remove_socket(transport, &active_socket->fd);
+ TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
+ continue;
+ }
+ }
+
+ /*================== TNET_POLLERR ==================*/
+ if(context->ufds[i].revents & (TNET_POLLERR)) {
fd = active_socket->fd;
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLERR(%d)", transport->description, fd);
-
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLERR(%d)", transport->description, fd);
+
tnet_transport_remove_socket(transport, &active_socket->fd);
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
- continue;
- }
-
- /*================== TNET_POLLNVAL ==================*/
- if(context->ufds[i].revents & (TNET_POLLNVAL)){
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
+ continue;
+ }
+
+ /*================== TNET_POLLNVAL ==================*/
+ if(context->ufds[i].revents & (TNET_POLLNVAL)) {
fd = active_socket->fd;
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLNVAL(%d)", transport->description, fd);
-
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLNVAL(%d)", transport->description, fd);
+
tnet_transport_remove_socket(transport, &active_socket->fd);
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
- continue;
- }
-
- /*================== POLLIN ==================*/
- if(context->ufds[i].revents & TNET_POLLIN)
- {
- tsk_size_t len = 0;
- void* buffer = tsk_null;
- tnet_transport_event_t* e;
-
- // TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLIN(%d)", transport->description, active_socket->fd);
-
- /* check whether the socket is paused or not */
- if(active_socket->paused){
- TSK_DEBUG_INFO("Socket is paused");
- goto TNET_POLLIN_DONE;
- }
-
- /* Retrieve the amount of pending data.
- * IMPORTANT: If you are using Symbian please update your SDK to the latest build (August 2009) to have 'FIONREAD'.
- * This apply whatever you are using the 3rd or 5th edition.
- * Download link: http://wiki.forum.nokia.com/index.php/Open_C/C%2B%2B_Release_History
- */
- ret = tnet_ioctlt(active_socket->fd, FIONREAD, &len);
- if((ret < 0 || !len) && is_stream){
- /* It's probably an incoming connection --> try to accept() it */
- int listening = 0, remove_socket = 0;
- socklen_t socklen = sizeof(listening);
-
- TSK_DEBUG_INFO("ioctlt(%d), len=%u returned zero or failed", active_socket->fd, (unsigned)len);
-
- // check if socket is listening
- if(getsockopt(active_socket->fd, SOL_SOCKET, SO_ACCEPTCONN, &listening, &socklen) != 0){
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
+ continue;
+ }
+
+ /*================== POLLIN ==================*/
+ if(context->ufds[i].revents & TNET_POLLIN) {
+ tsk_size_t len = 0;
+ void* buffer = tsk_null;
+ tnet_transport_event_t* e;
+
+ // TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLIN(%d)", transport->description, active_socket->fd);
+
+ /* check whether the socket is paused or not */
+ if(active_socket->paused) {
+ TSK_DEBUG_INFO("Socket is paused");
+ goto TNET_POLLIN_DONE;
+ }
+
+ /* Retrieve the amount of pending data.
+ * IMPORTANT: If you are using Symbian please update your SDK to the latest build (August 2009) to have 'FIONREAD'.
+ * This apply whatever you are using the 3rd or 5th edition.
+ * Download link: http://wiki.forum.nokia.com/index.php/Open_C/C%2B%2B_Release_History
+ */
+ ret = tnet_ioctlt(active_socket->fd, FIONREAD, &len);
+ if((ret < 0 || !len) && is_stream) {
+ /* It's probably an incoming connection --> try to accept() it */
+ int listening = 0, remove_socket = 0;
+ socklen_t socklen = sizeof(listening);
+
+ TSK_DEBUG_INFO("ioctlt(%d), len=%u returned zero or failed", active_socket->fd, (unsigned)len);
+
+ // check if socket is listening
+ if(getsockopt(active_socket->fd, SOL_SOCKET, SO_ACCEPTCONN, &listening, &socklen) != 0) {
#if defined(BSD) /* old FreeBSD versions (and OSX up to Lion) do not support SO_ACCEPTCONN */
listening = 1;
#else
- TNET_PRINT_LAST_ERROR("getsockopt(SO_ACCEPTCONN, %d) failed\n", active_socket->fd);
+ TNET_PRINT_LAST_ERROR("getsockopt(SO_ACCEPTCONN, %d) failed\n", active_socket->fd);
/* not socket accepted -> no socket to remove */
goto TNET_POLLIN_DONE;
#endif
- }
- if (listening){
- if((fd = accept(active_socket->fd, tsk_null, tsk_null)) != TNET_INVALID_SOCKET){
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_ACCEPT(fd=%d)", transport->description, fd);
- addSocket(fd, transport->master->type, transport, tsk_true, tsk_false, tsk_null);
- TSK_RUNNABLE_ENQUEUE(transport, event_accepted, transport->callback_data, fd);
- if(active_socket->tlshandle){
- transport_socket_xt* tls_socket;
- if((tls_socket = getSocket(context, fd))){
- if(tnet_tls_socket_accept(tls_socket->tlshandle) != 0){
- TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
- tnet_transport_remove_socket(transport, &fd);
- TNET_PRINT_LAST_ERROR("SSL_accept() failed");
- continue;
- }
- }
- }
- }
- else{
- TNET_PRINT_LAST_ERROR("accept(%d) failed", active_socket->fd);
- remove_socket = 1;
- }
- }
- else{
- TSK_DEBUG_INFO("Closing socket with fd = %d because ioctlt() returned zero or failed", active_socket->fd);
- remove_socket = 1;
- }
-
- if(remove_socket){
- fd = active_socket->fd;
- tnet_transport_remove_socket(transport, &active_socket->fd);
- TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
- continue;
- }
- goto TNET_POLLIN_DONE;
- }
-
- if(len <= 0){
+ }
+ if (listening) {
+ if((fd = accept(active_socket->fd, tsk_null, tsk_null)) != TNET_INVALID_SOCKET) {
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_ACCEPT(fd=%d)", transport->description, fd);
+ addSocket(fd, transport->master->type, transport, tsk_true, tsk_false, tsk_null);
+ TSK_RUNNABLE_ENQUEUE(transport, event_accepted, transport->callback_data, fd);
+ if(active_socket->tlshandle) {
+ transport_socket_xt* tls_socket;
+ if((tls_socket = getSocket(context, fd))) {
+ if(tnet_tls_socket_accept(tls_socket->tlshandle) != 0) {
+ TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
+ tnet_transport_remove_socket(transport, &fd);
+ TNET_PRINT_LAST_ERROR("SSL_accept() failed");
+ continue;
+ }
+ }
+ }
+ }
+ else {
+ TNET_PRINT_LAST_ERROR("accept(%d) failed", active_socket->fd);
+ remove_socket = 1;
+ }
+ }
+ else {
+ TSK_DEBUG_INFO("Closing socket with fd = %d because ioctlt() returned zero or failed", active_socket->fd);
+ remove_socket = 1;
+ }
+
+ if(remove_socket) {
+ fd = active_socket->fd;
+ tnet_transport_remove_socket(transport, &active_socket->fd);
+ TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, fd);
+ continue;
+ }
+ goto TNET_POLLIN_DONE;
+ }
+
+ if(len <= 0) {
#if ANDROID
- // workaround for indoona OSX which sends bodiless UDP packets
- // vand Android requires to call recv() even if len is equal to zero
- if(len == 0 && ret == 0){
- static char __fake_buff[1];
- ret = recv(active_socket->fd, __fake_buff, len, 0);
- }
+ // workaround for indoona OSX which sends bodiless UDP packets
+ // vand Android requires to call recv() even if len is equal to zero
+ if(len == 0 && ret == 0) {
+ static char __fake_buff[1];
+ ret = recv(active_socket->fd, __fake_buff, len, 0);
+ }
#endif
- goto TNET_POLLIN_DONE;
- }
-
- if (!(buffer = tsk_calloc(len, sizeof(uint8_t)))) {
- TSK_DEBUG_ERROR("TSK_CALLOC FAILED");
- goto TNET_POLLIN_DONE;
- }
-
- // Retrieve the remote address
- if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
- ret = tnet_getpeername(active_socket->fd, &remote_addr);
- }
-
- // Receive the waiting data
- if (active_socket->tlshandle) {
- int isEncrypted;
- tsk_size_t tlslen = len;
- if ((ret = tnet_tls_socket_recv(active_socket->tlshandle, &buffer, &tlslen, &isEncrypted)) == 0) {
- if (isEncrypted) {
- TSK_FREE(buffer);
- goto TNET_POLLIN_DONE;
- }
- if (ret == 0) {
- len = ret = tlslen;
- }
- }
- }
- else {
- if (is_stream) {
- ret = tnet_sockfd_recv(active_socket->fd, buffer, len, 0);
- }
- else {
- ret = tnet_sockfd_recvfrom(active_socket->fd, buffer, len, 0, (struct sockaddr*)&remote_addr);
- }
- }
-
- if(ret < 0){
- TSK_FREE(buffer);
+ goto TNET_POLLIN_DONE;
+ }
+
+ if (!(buffer = tsk_calloc(len, sizeof(uint8_t)))) {
+ TSK_DEBUG_ERROR("TSK_CALLOC FAILED");
+ goto TNET_POLLIN_DONE;
+ }
+
+ // Retrieve the remote address
+ if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
+ ret = tnet_getpeername(active_socket->fd, &remote_addr);
+ }
+
+ // Receive the waiting data
+ if (active_socket->tlshandle) {
+ int isEncrypted;
+ tsk_size_t tlslen = len;
+ if ((ret = tnet_tls_socket_recv(active_socket->tlshandle, &buffer, &tlslen, &isEncrypted)) == 0) {
+ if (isEncrypted) {
+ TSK_FREE(buffer);
+ goto TNET_POLLIN_DONE;
+ }
+ if (ret == 0) {
+ len = ret = tlslen;
+ }
+ }
+ }
+ else {
+ if (is_stream) {
+ ret = tnet_sockfd_recv(active_socket->fd, buffer, len, 0);
+ }
+ else {
+ ret = tnet_sockfd_recvfrom(active_socket->fd, buffer, len, 0, (struct sockaddr*)&remote_addr);
+ }
+ }
+
+ if(ret < 0) {
+ TSK_FREE(buffer);
status = tnet_geterrno();
- // do not remove the socket for i/o pending errors
+ // do not remove the socket for i/o pending errors
if (status == TNET_ERROR_WOULDBLOCK || status == TNET_ERROR_INPROGRESS || status == TNET_ERROR_EAGAIN) {
TSK_DEBUG_WARN("recv returned error code:%d", status);
}
@@ -805,61 +802,62 @@ void *tnet_transport_mainthread(void *param)
TNET_PRINT_LAST_ERROR("recv/recvfrom have failed");
removeSocket(i, context);
}
- goto TNET_POLLIN_DONE;
- }
-
- if((len != (tsk_size_t)ret) && len){
- len = (tsk_size_t)ret;
- // buffer = tsk_realloc(buffer, len);
- }
-
- if(len > 0){
+ goto TNET_POLLIN_DONE;
+ }
+
+ if((len != (tsk_size_t)ret) && len) {
+ len = (tsk_size_t)ret;
+ // buffer = tsk_realloc(buffer, len);
+ }
+
+ if(len > 0) {
transport->bytes_in += len;
- e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
- e->data = buffer, buffer = tsk_null;
- e->size = len;
- e->remote_addr = remote_addr;
-
- TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
- }
- TSK_FREE(buffer);
+ e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
+ e->data = buffer, buffer = tsk_null;
+ e->size = len;
+ e->remote_addr = remote_addr;
+
+ TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
+ }
+ TSK_FREE(buffer);
TNET_POLLIN_DONE:
- /*context->ufds[i].revents &= ~TNET_POLLIN*/;
- }
+ /*context->ufds[i].revents &= ~TNET_POLLIN*/
+ ;
+ }
- /*================== TNET_POLLOUT ==================*/
- if(context->ufds[i].revents & TNET_POLLOUT){
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLOUT", transport->description);
- if(!active_socket->connected){
- active_socket->connected = tsk_true;
- TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, active_socket->fd);
- }
- //else{
- context->ufds[i].events &= ~TNET_POLLOUT;
- //}
- }
+ /*================== TNET_POLLOUT ==================*/
+ if(context->ufds[i].revents & TNET_POLLOUT) {
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLOUT", transport->description);
+ if(!active_socket->connected) {
+ active_socket->connected = tsk_true;
+ TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, active_socket->fd);
+ }
+ //else{
+ context->ufds[i].events &= ~TNET_POLLOUT;
+ //}
+ }
- /*================== TNET_POLLPRI ==================*/
- if(context->ufds[i].revents & TNET_POLLPRI){
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLPRI", transport->description);
- }
+ /*================== TNET_POLLPRI ==================*/
+ if(context->ufds[i].revents & TNET_POLLPRI) {
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- TNET_POLLPRI", transport->description);
+ }
context->ufds[i].revents = 0;
- }/* for */
+ }/* for */
done:
- /* unlock context */
- tsk_safeobj_unlock(context);
+ /* unlock context */
+ tsk_safeobj_unlock(context);
- } /* while */
+ } /* while */
bail:
-
- TSK_DEBUG_INFO("Stopped [%s] server with IP {%s} on port {%d}", transport->description, transport->master->ip, transport->master->port);
- return 0;
+
+ TSK_DEBUG_INFO("Stopped [%s] server with IP {%s} on port {%d}", transport->description, transport->master->ip, transport->master->port);
+ return 0;
}
@@ -871,7 +869,7 @@ bail:
void* tnet_transport_context_create()
{
- return tsk_object_new(tnet_transport_context_def_t);
+ return tsk_object_new(tnet_transport_context_def_t);
}
@@ -880,32 +878,31 @@ void* tnet_transport_context_create()
//
static tsk_object_t* transport_context_ctor(tsk_object_t * self, va_list * app)
{
- transport_context_t *context = self;
- if(context){
+ transport_context_t *context = self;
+ if(context) {
context->pipeR = context->pipeW = -1;
- tsk_safeobj_init(context);
- }
- return self;
+ tsk_safeobj_init(context);
+ }
+ return self;
}
static tsk_object_t* transport_context_dtor(tsk_object_t * self)
-{
- transport_context_t *context = self;
- if(context){
- while(context->count){
- removeSocket(0, context);
- }
- tsk_safeobj_deinit(context);
- }
- return self;
+{
+ transport_context_t *context = self;
+ if(context) {
+ while(context->count) {
+ removeSocket(0, context);
+ }
+ tsk_safeobj_deinit(context);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_transport_context_def_s =
-{
-sizeof(transport_context_t),
-transport_context_ctor,
-transport_context_dtor,
-tsk_null,
+static const tsk_object_def_t tnet_transport_context_def_s = {
+ sizeof(transport_context_t),
+ transport_context_ctor,
+ transport_context_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_transport_context_def_t = &tnet_transport_context_def_s;
diff --git a/tinyNET/src/tnet_transport_win32.c b/tinyNET/src/tnet_transport_win32.c
index 6f7886f..626cccc 100755
--- a/tinyNET/src/tnet_transport_win32.c
+++ b/tinyNET/src/tnet_transport_win32.c
@@ -36,28 +36,26 @@
#if TNET_UNDER_WINDOWS && !TNET_USE_POLL
/*== Socket description ==*/
-typedef struct transport_socket_xs
-{
- tnet_fd_t fd;
- unsigned owner : 1;
- unsigned connected : 1;
- unsigned paused : 1;
-
- tnet_socket_type_t type;
- tnet_tls_socket_handle_t* tlshandle;
+typedef struct transport_socket_xs {
+ tnet_fd_t fd;
+ unsigned owner : 1;
+ unsigned connected : 1;
+ unsigned paused : 1;
+
+ tnet_socket_type_t type;
+ tnet_tls_socket_handle_t* tlshandle;
}
transport_socket_xt;
/*== Transport context structure definition ==*/
-typedef struct transport_context_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct transport_context_s {
+ TSK_DECLARE_OBJECT;
- tsk_size_t count;
- WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS];
- transport_socket_xt* sockets[WSA_MAXIMUM_WAIT_EVENTS];
+ tsk_size_t count;
+ WSAEVENT events[WSA_MAXIMUM_WAIT_EVENTS];
+ transport_socket_xt* sockets[WSA_MAXIMUM_WAIT_EVENTS];
- TSK_DECLARE_SAFEOBJ;
+ TSK_DECLARE_SAFEOBJ;
}
transport_context_t;
@@ -68,54 +66,52 @@ static int removeSocket(int index, transport_context_t *context);
/* Checks if socket is connected */
int tnet_transport_isconnected(const tnet_transport_handle_t *handle, tnet_fd_t fd)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- transport_context_t *context;
- tsk_size_t i;
-
- if (!transport)
- {
- TSK_DEBUG_ERROR("Invalid server handle.");
- return 0;
- }
-
- context = (transport_context_t*)transport->context;
- for (i = 0; i < context->count; i++)
- {
- const transport_socket_xt* socket = context->sockets[i];
- if (socket->fd == fd){
- return socket->connected;
- }
- }
-
- return 0;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ transport_context_t *context;
+ tsk_size_t i;
+
+ if (!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ return 0;
+ }
+
+ context = (transport_context_t*)transport->context;
+ for (i = 0; i < context->count; i++) {
+ const transport_socket_xt* socket = context->sockets[i];
+ if (socket->fd == fd) {
+ return socket->connected;
+ }
+ }
+
+ return 0;
}
int tnet_transport_have_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
- if (!transport){
- TSK_DEBUG_ERROR("Invalid server handle.");
- return 0;
- }
+ if (!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ return 0;
+ }
- return (getSocket((transport_context_t*)transport->context, fd) != 0);
+ return (getSocket((transport_context_t*)transport->context, fd) != 0);
}
const tnet_tls_socket_handle_t* tnet_transport_get_tlshandle(const tnet_transport_handle_t *handle, tnet_fd_t fd)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- transport_socket_xt *socket;
-
- if (!transport){
- TSK_DEBUG_ERROR("Invalid server handle.");
- return 0;
- }
-
- if ((socket = getSocket((transport_context_t*)transport->context, fd))){
- return socket->tlshandle;
- }
- return 0;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ transport_socket_xt *socket;
+
+ if (!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ return 0;
+ }
+
+ if ((socket = getSocket((transport_context_t*)transport->context, fd))) {
+ return socket->tlshandle;
+ }
+ return 0;
}
int tnet_transport_add_socket_2(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle, const char* dst_host, tnet_port_t dst_port, struct tnet_proxyinfo_s* proxy_info)
@@ -132,102 +128,102 @@ int tnet_transport_add_socket_2(const tnet_transport_handle_t *handle, tnet_fd_t
*/
int tnet_transport_add_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tnet_socket_type_t type, tsk_bool_t take_ownership, tsk_bool_t isClient, tnet_tls_socket_handle_t* tlsHandle)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- transport_context_t* context;
- int ret = -1;
-
- if (!transport){
- TSK_DEBUG_ERROR("Invalid server handle.");
- return ret;
- }
-
- if (!(context = (transport_context_t*)transport->context)){
- TSK_DEBUG_ERROR("Invalid context.");
- return -2;
- }
-
- if (TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)){
- transport->tls.enabled = tsk_true;
- }
-
- addSocket(fd, type, transport, take_ownership, isClient, tlsHandle);
-
- if (WSAEventSelect(fd, context->events[context->count - 1], FD_ALL_EVENTS) == SOCKET_ERROR){
- removeSocket((int)(context->count - 1), context);
- TNET_PRINT_LAST_ERROR("WSAEventSelect have failed.");
- return -1;
- }
-
- /* Signal if transport is running */
- if (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started){
- if (WSASetEvent(context->events[0])){
- TSK_DEBUG_INFO("New socket added to the network transport.");
- return 0;
- }
- TSK_DEBUG_ERROR("Transport not started yet");
- return -1;
- }
-
- TSK_DEBUG_INFO("Adding socket delayed");
- return 0;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ transport_context_t* context;
+ int ret = -1;
+
+ if (!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ return ret;
+ }
+
+ if (!(context = (transport_context_t*)transport->context)) {
+ TSK_DEBUG_ERROR("Invalid context.");
+ return -2;
+ }
+
+ if (TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)) {
+ transport->tls.enabled = tsk_true;
+ }
+
+ addSocket(fd, type, transport, take_ownership, isClient, tlsHandle);
+
+ if (WSAEventSelect(fd, context->events[context->count - 1], FD_ALL_EVENTS) == SOCKET_ERROR) {
+ removeSocket((int)(context->count - 1), context);
+ TNET_PRINT_LAST_ERROR("WSAEventSelect have failed.");
+ return -1;
+ }
+
+ /* Signal if transport is running */
+ if (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started) {
+ if (WSASetEvent(context->events[0])) {
+ TSK_DEBUG_INFO("New socket added to the network transport.");
+ return 0;
+ }
+ TSK_DEBUG_ERROR("Transport not started yet");
+ return -1;
+ }
+
+ TSK_DEBUG_INFO("Adding socket delayed");
+ return 0;
}
int tnet_transport_pause_socket(const tnet_transport_handle_t *handle, tnet_fd_t fd, tsk_bool_t pause)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- transport_context_t *context;
- transport_socket_xt* socket;
-
- if (!transport || !(context = (transport_context_t*)transport->context)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- if ((socket = getSocket(context, fd))){
- socket->paused = pause;
- }
- else{
- TSK_DEBUG_WARN("Socket does not exist in this context");
- }
- return 0;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ transport_context_t *context;
+ transport_socket_xt* socket;
+
+ if (!transport || !(context = (transport_context_t*)transport->context)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ if ((socket = getSocket(context, fd))) {
+ socket->paused = pause;
+ }
+ else {
+ TSK_DEBUG_WARN("Socket does not exist in this context");
+ }
+ return 0;
}
/* Remove socket
*/
int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_t* fd)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- transport_context_t *context;
- int ret = -1;
- tsk_size_t i;
- tsk_bool_t found = tsk_false;
-
- if (!transport || !(context = (transport_context_t*)transport->context)){
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- for (i = 0; i < context->count; i++){
- if (context->sockets[i]->fd == *fd){
- removeSocket((int)i, context);
- found = tsk_true;
- TSK_RUNNABLE_ENQUEUE(transport, event_removed, transport->callback_data, *fd);
- *fd = TNET_INVALID_FD;
- break;
- }
- }
-
- if (found){
- /* Signal */
- if (WSASetEvent(context->events[0])){
- TSK_DEBUG_INFO("Old socket removed from the network transport.");
- return 0;
- }
- }
-
- // ...
-
- return -1;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ transport_context_t *context;
+ int ret = -1;
+ tsk_size_t i;
+ tsk_bool_t found = tsk_false;
+
+ if (!transport || !(context = (transport_context_t*)transport->context)) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+
+ for (i = 0; i < context->count; i++) {
+ if (context->sockets[i]->fd == *fd) {
+ removeSocket((int)i, context);
+ found = tsk_true;
+ TSK_RUNNABLE_ENQUEUE(transport, event_removed, transport->callback_data, *fd);
+ *fd = TNET_INVALID_FD;
+ break;
+ }
+ }
+
+ if (found) {
+ /* Signal */
+ if (WSASetEvent(context->events[0])) {
+ TSK_DEBUG_INFO("Old socket removed from the network transport.");
+ return 0;
+ }
+ }
+
+ // ...
+
+ return -1;
}
/*
@@ -235,58 +231,58 @@ int tnet_transport_remove_socket(const tnet_transport_handle_t *handle, tnet_fd_
*/
tsk_size_t tnet_transport_send(const tnet_transport_handle_t *handle, tnet_fd_t from, const void* buf, tsk_size_t size)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- int ret = -1;
- tsk_size_t sent = 0;
-
- if (!transport){
- TSK_DEBUG_ERROR("Invalid transport handle.");
- goto bail;
- }
-
- while (sent < size) {
- int try_guard = 10;
- if (transport->tls.enabled){
- transport_socket_xt* socket = getSocket(transport->context, from);
- if (socket && socket->tlshandle) {
- if (tnet_tls_socket_send(socket->tlshandle, buf, size) == 0) {
- sent = size;
- }
- else {
- TSK_DEBUG_ERROR("Tring to use a socket without TLS handle to send data");
- }
- goto bail; // TLS do not retry
- }
- }
- else {
- WSABUF wsaBuffer;
- DWORD numberOfBytesSent = 0;
- wsaBuffer.buf = ((CHAR*)buf) + sent;
- wsaBuffer.len = (ULONG)(size - sent);
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ int ret = -1;
+ tsk_size_t sent = 0;
+
+ if (!transport) {
+ TSK_DEBUG_ERROR("Invalid transport handle.");
+ goto bail;
+ }
+
+ while (sent < size) {
+ int try_guard = 10;
+ if (transport->tls.enabled) {
+ transport_socket_xt* socket = getSocket(transport->context, from);
+ if (socket && socket->tlshandle) {
+ if (tnet_tls_socket_send(socket->tlshandle, buf, size) == 0) {
+ sent = size;
+ }
+ else {
+ TSK_DEBUG_ERROR("Tring to use a socket without TLS handle to send data");
+ }
+ goto bail; // TLS do not retry
+ }
+ }
+ else {
+ WSABUF wsaBuffer;
+ DWORD numberOfBytesSent = 0;
+ wsaBuffer.buf = ((CHAR*)buf) + sent;
+ wsaBuffer.len = (ULONG)(size - sent);
try_again:
- if ((ret = WSASend(from, &wsaBuffer, 1, &numberOfBytesSent, 0, NULL, NULL)) == SOCKET_ERROR) {
- ret = WSAGetLastError();
- if (ret == WSA_IO_PENDING || ret == WSAEWOULDBLOCK) {
- TSK_DEBUG_INFO("SendTCP() - WouldBlock. Retrying...");
- if (try_guard--) {
- tsk_thread_sleep(10);
- goto try_again;
- }
- }
- else {
- TNET_PRINT_LAST_ERROR("WSASend have failed.");
- goto bail;
- }
- }
- else {
- sent += numberOfBytesSent;
- }
- }
- }
+ if ((ret = WSASend(from, &wsaBuffer, 1, &numberOfBytesSent, 0, NULL, NULL)) == SOCKET_ERROR) {
+ ret = WSAGetLastError();
+ if (ret == WSA_IO_PENDING || ret == WSAEWOULDBLOCK) {
+ TSK_DEBUG_INFO("SendTCP() - WouldBlock. Retrying...");
+ if (try_guard--) {
+ tsk_thread_sleep(10);
+ goto try_again;
+ }
+ }
+ else {
+ TNET_PRINT_LAST_ERROR("WSASend have failed.");
+ goto bail;
+ }
+ }
+ else {
+ sent += numberOfBytesSent;
+ }
+ }
+ }
bail:
transport->bytes_out += sent;
- return sent;
+ return sent;
}
/*
@@ -294,27 +290,27 @@ bail:
*/
tsk_size_t tnet_transport_sendto(const tnet_transport_handle_t *handle, tnet_fd_t from, const struct sockaddr *to, const void* buf, tsk_size_t size)
{
- tnet_transport_t *transport = (tnet_transport_t*)handle;
- int numberOfBytesSent = 0;
+ tnet_transport_t *transport = (tnet_transport_t*)handle;
+ int numberOfBytesSent = 0;
- if (!transport) {
- TSK_DEBUG_ERROR("Invalid server handle.");
- goto bail;
- }
+ if (!transport) {
+ TSK_DEBUG_ERROR("Invalid server handle.");
+ goto bail;
+ }
- if (!TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)) {
- TSK_DEBUG_ERROR("In order to use sendto() you must use an udp transport.");
- goto bail;
- }
+ if (!TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)) {
+ TSK_DEBUG_ERROR("In order to use sendto() you must use an udp transport.");
+ goto bail;
+ }
- if ((numberOfBytesSent = tnet_sockfd_sendto(from, to, buf, size)) <= 0) {
- TNET_PRINT_LAST_ERROR("sendto have failed.");
- goto bail;
- }
+ if ((numberOfBytesSent = tnet_sockfd_sendto(from, to, buf, size)) <= 0) {
+ TNET_PRINT_LAST_ERROR("sendto have failed.");
+ goto bail;
+ }
bail:
transport->bytes_out += numberOfBytesSent;
- return numberOfBytesSent;
+ return numberOfBytesSent;
}
@@ -327,472 +323,472 @@ bail:
/*== CAllback function to check if we should accept the new socket or not == */
int CALLBACK AcceptCondFunc(LPWSABUF lpCallerId, LPWSABUF lpCallerData, LPQOS lpSQos, LPQOS lpGQos, LPWSABUF lpCalleeId, LPWSABUF lpCalleeData, GROUP FAR *Group, DWORD_PTR CallbackData)
{
- transport_context_t *context = (transport_context_t*)CallbackData;
- return context->count < WSA_MAXIMUM_WAIT_EVENTS ? CF_ACCEPT : CF_REJECT;
+ transport_context_t *context = (transport_context_t*)CallbackData;
+ return context->count < WSA_MAXIMUM_WAIT_EVENTS ? CF_ACCEPT : CF_REJECT;
}
/*== Get socket ==*/
static transport_socket_xt* getSocket(transport_context_t *context, tnet_fd_t fd)
{
- tsk_size_t i;
- transport_socket_xt* ret = 0;
-
- if (context) {
- tsk_safeobj_lock(context);
- for (i = 0; i < context->count; i++) {
- if (context->sockets[i]->fd == fd) {
- ret = context->sockets[i];
- break;
- }
- }
- tsk_safeobj_unlock(context);
- }
-
- return ret;
+ tsk_size_t i;
+ transport_socket_xt* ret = 0;
+
+ if (context) {
+ tsk_safeobj_lock(context);
+ for (i = 0; i < context->count; i++) {
+ if (context->sockets[i]->fd == fd) {
+ ret = context->sockets[i];
+ break;
+ }
+ }
+ tsk_safeobj_unlock(context);
+ }
+
+ return ret;
}
/*== Add new socket ==*/
static int addSocket(tnet_fd_t fd, tnet_socket_type_t type, tnet_transport_t *transport, tsk_bool_t take_ownership, tsk_bool_t is_client, tnet_tls_socket_handle_t* tlsHandle)
{
- transport_context_t *context;
+ transport_context_t *context;
- if (TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)) {
+ if (TNET_SOCKET_TYPE_IS_TLS(type) || TNET_SOCKET_TYPE_IS_WSS(type)) {
#if !HAVE_OPENSSL
- TSK_DEBUG_ERROR("Cannot create TLS socket: OpenSSL missing");
- return -2;
+ TSK_DEBUG_ERROR("Cannot create TLS socket: OpenSSL missing");
+ return -2;
#endif
- }
-
- if ((context = transport ? transport->context : tsk_null)) {
- transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
- sock->fd = fd;
- sock->type = type;
- sock->owner = take_ownership ? 1 : 0;
-
- if ((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled) {
- if (tlsHandle) {
- sock->tlshandle = tsk_object_ref(tlsHandle);
- }
- else{
+ }
+
+ if ((context = transport ? transport->context : tsk_null)) {
+ transport_socket_xt *sock = tsk_calloc(1, sizeof(transport_socket_xt));
+ sock->fd = fd;
+ sock->type = type;
+ sock->owner = take_ownership ? 1 : 0;
+
+ if ((TNET_SOCKET_TYPE_IS_TLS(sock->type) || TNET_SOCKET_TYPE_IS_WSS(sock->type)) && transport->tls.enabled) {
+ if (tlsHandle) {
+ sock->tlshandle = tsk_object_ref(tlsHandle);
+ }
+ else {
#if HAVE_OPENSSL
- sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
+ sock->tlshandle = tnet_tls_socket_create(sock->fd, is_client ? transport->tls.ctx_client : transport->tls.ctx_server);
#endif
- }
- }
+ }
+ }
- tsk_safeobj_lock(context);
- context->events[context->count] = WSACreateEvent();
- context->sockets[context->count] = sock;
+ tsk_safeobj_lock(context);
+ context->events[context->count] = WSACreateEvent();
+ context->sockets[context->count] = sock;
- context->count++;
+ context->count++;
- TSK_DEBUG_INFO("Transport[%s] sockets count = %u", transport->description, context->count);
+ TSK_DEBUG_INFO("Transport[%s] sockets count = %u", transport->description, context->count);
- tsk_safeobj_unlock(context);
+ tsk_safeobj_unlock(context);
- return 0;
- }
- else {
- TSK_DEBUG_ERROR("Context is Null.");
- return -1;
- }
- }
+ return 0;
+ }
+ else {
+ TSK_DEBUG_ERROR("Context is Null.");
+ return -1;
+ }
+}
/*== Remove socket ==*/
static int removeSocket(int index, transport_context_t *context)
{
- tsk_size_t i;
+ tsk_size_t i;
- tsk_safeobj_lock(context);
+ tsk_safeobj_lock(context);
- if (index < (int)context->count) {
+ if (index < (int)context->count) {
- /* Close the socket if we are the owner. */
- if (context->sockets[index]->owner) {
- tnet_sockfd_close(&(context->sockets[index]->fd));
- }
+ /* Close the socket if we are the owner. */
+ if (context->sockets[index]->owner) {
+ tnet_sockfd_close(&(context->sockets[index]->fd));
+ }
- /* Free tls context */
- if (context->sockets[index]->tlshandle) {
- TSK_OBJECT_SAFE_FREE(context->sockets[index]->tlshandle);
- }
- // Free socket
- TSK_FREE(context->sockets[index]);
+ /* Free tls context */
+ if (context->sockets[index]->tlshandle) {
+ TSK_OBJECT_SAFE_FREE(context->sockets[index]->tlshandle);
+ }
+ // Free socket
+ TSK_FREE(context->sockets[index]);
- // Close event
- WSACloseEvent(context->events[index]);
+ // Close event
+ WSACloseEvent(context->events[index]);
- for (i = index; i < context->count - 1; i++) {
- context->sockets[i] = context->sockets[i + 1];
- context->events[i] = context->events[i + 1];
- }
+ for (i = index; i < context->count - 1; i++) {
+ context->sockets[i] = context->sockets[i + 1];
+ context->events[i] = context->events[i + 1];
+ }
- context->sockets[context->count - 1] = 0;
- context->events[context->count - 1] = 0;
+ context->sockets[context->count - 1] = 0;
+ context->events[context->count - 1] = 0;
- context->count--;
- TSK_DEBUG_INFO("Transport sockets count = %u", context->count);
- }
+ context->count--;
+ TSK_DEBUG_INFO("Transport sockets count = %u", context->count);
+ }
- tsk_safeobj_unlock(context);
+ tsk_safeobj_unlock(context);
- return 0;
+ return 0;
}
/*=== stop all threads */
int tnet_transport_stop(tnet_transport_t *transport)
{
- int ret;
-
- if ((ret = tsk_runnable_stop(TSK_RUNNABLE(transport)))){
- return ret;
- }
-
- if (transport->mainThreadId[0]){
- WSASetEvent(((transport_context_t*)(transport->context))->events[0]);
- return tsk_thread_join(transport->mainThreadId);
- }
- else{
- /* already stoppped */
- return 0;
- }
+ int ret;
+
+ if ((ret = tsk_runnable_stop(TSK_RUNNABLE(transport)))) {
+ return ret;
+ }
+
+ if (transport->mainThreadId[0]) {
+ WSASetEvent(((transport_context_t*)(transport->context))->events[0]);
+ return tsk_thread_join(transport->mainThreadId);
+ }
+ else {
+ /* already stoppped */
+ return 0;
+ }
}
int tnet_transport_prepare(tnet_transport_t *transport)
{
- int ret = -1;
- transport_context_t *context;
-
- if (!transport || !transport->context){
- TSK_DEBUG_ERROR("Invalid parameter.");
- return -1;
- }
- else{
- context = transport->context;
- }
-
- if (transport->prepared){
- TSK_DEBUG_ERROR("Transport already prepared.");
- return -2;
- }
-
- /* Prepare master */
- if (!transport->master){
- if ((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))){
- tsk_strupdate(&transport->local_ip, transport->master->ip);
- transport->bind_local_port = transport->master->port;
- }
- else{
- TSK_DEBUG_ERROR("Failed to create master socket");
- return -3;
- }
- }
-
- /* Start listening */
- if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
- if ((ret = tnet_sockfd_listen(transport->master->fd, WSA_MAXIMUM_WAIT_EVENTS))) {
- TNET_PRINT_LAST_ERROR("listen have failed.");
- goto bail;
- }
- }
-
- /* Add the master socket to the context. */
- // don't take ownership: will be closed by the dctor() when refCount==0
- // otherwise will be closed twice: dctor() and removeSocket()
- if ((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false, tsk_null))) {
- TSK_DEBUG_ERROR("Failed to add master socket");
- goto bail;
- }
-
- /* set events on master socket */
- if ((ret = WSAEventSelect(transport->master->fd, context->events[context->count - 1], FD_ALL_EVENTS) == SOCKET_ERROR)) {
- TNET_PRINT_LAST_ERROR("WSAEventSelect have failed.");
- goto bail;
- }
-
- transport->prepared = tsk_true;
+ int ret = -1;
+ transport_context_t *context;
+
+ if (!transport || !transport->context) {
+ TSK_DEBUG_ERROR("Invalid parameter.");
+ return -1;
+ }
+ else {
+ context = transport->context;
+ }
+
+ if (transport->prepared) {
+ TSK_DEBUG_ERROR("Transport already prepared.");
+ return -2;
+ }
+
+ /* Prepare master */
+ if (!transport->master) {
+ if ((transport->master = tnet_socket_create(transport->local_host, transport->req_local_port, transport->type))) {
+ tsk_strupdate(&transport->local_ip, transport->master->ip);
+ transport->bind_local_port = transport->master->port;
+ }
+ else {
+ TSK_DEBUG_ERROR("Failed to create master socket");
+ return -3;
+ }
+ }
+
+ /* Start listening */
+ if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
+ if ((ret = tnet_sockfd_listen(transport->master->fd, WSA_MAXIMUM_WAIT_EVENTS))) {
+ TNET_PRINT_LAST_ERROR("listen have failed.");
+ goto bail;
+ }
+ }
+
+ /* Add the master socket to the context. */
+ // don't take ownership: will be closed by the dctor() when refCount==0
+ // otherwise will be closed twice: dctor() and removeSocket()
+ if ((ret = addSocket(transport->master->fd, transport->master->type, transport, tsk_false, tsk_false, tsk_null))) {
+ TSK_DEBUG_ERROR("Failed to add master socket");
+ goto bail;
+ }
+
+ /* set events on master socket */
+ if ((ret = WSAEventSelect(transport->master->fd, context->events[context->count - 1], FD_ALL_EVENTS) == SOCKET_ERROR)) {
+ TNET_PRINT_LAST_ERROR("WSAEventSelect have failed.");
+ goto bail;
+ }
+
+ transport->prepared = tsk_true;
bail:
- return ret;
+ return ret;
}
int tnet_transport_unprepare(tnet_transport_t *transport)
{
- int ret = -1;
- transport_context_t *context;
-
- if (!transport || !transport->context){
- TSK_DEBUG_ERROR("Invalid parameter.");
- return -1;
- }
- else{
- context = transport->context;
- }
-
- if (!transport->prepared){
- return 0;
- }
-
- transport->prepared = tsk_false;
-
- while (context->count){
- removeSocket(0, context); // safe
- }
- // destroy master as it has been close by removeSocket()
- TSK_OBJECT_SAFE_FREE(transport->master);
-
- return 0;
+ int ret = -1;
+ transport_context_t *context;
+
+ if (!transport || !transport->context) {
+ TSK_DEBUG_ERROR("Invalid parameter.");
+ return -1;
+ }
+ else {
+ context = transport->context;
+ }
+
+ if (!transport->prepared) {
+ return 0;
+ }
+
+ transport->prepared = tsk_false;
+
+ while (context->count) {
+ removeSocket(0, context); // safe
+ }
+ // destroy master as it has been close by removeSocket()
+ TSK_OBJECT_SAFE_FREE(transport->master);
+
+ return 0;
}
/*=== Main thread */
void* TSK_STDCALL tnet_transport_mainthread(void *param)
{
- tnet_transport_t *transport = (tnet_transport_t*)param;
- transport_context_t *context = (transport_context_t*)transport->context;
- DWORD evt;
- WSANETWORKEVENTS networkEvents;
- DWORD flags = 0;
- int ret;
-
- struct sockaddr_storage remote_addr = { 0 };
- WSAEVENT active_event;
- transport_socket_xt* active_socket;
- int index;
-
- TSK_DEBUG_INFO("Starting [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);
-
- while (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started) {
- /* Wait for multiple events */
- if ((evt = WSAWaitForMultipleEvents((DWORD)context->count, context->events, FALSE, WSA_INFINITE, FALSE)) == WSA_WAIT_FAILED) {
- TNET_PRINT_LAST_ERROR("WSAWaitForMultipleEvents have failed.");
- goto bail;
- }
-
- if (!TSK_RUNNABLE(transport)->running && !TSK_RUNNABLE(transport)->started) {
- goto bail;
- }
-
- /* lock context */
- tsk_safeobj_lock(context);
-
- /* Get active event and socket */
- index = (evt - WSA_WAIT_EVENT_0);
- active_event = context->events[index];
- if (!(active_socket = context->sockets[index])) {
- goto done;
- }
-
- /* Get the network events flags */
- if (WSAEnumNetworkEvents(active_socket->fd, active_event, &networkEvents) == SOCKET_ERROR) {
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
- TNET_PRINT_LAST_ERROR("WSAEnumNetworkEvents have failed.");
-
- tsk_safeobj_unlock(context);
- goto bail;
- }
-
- /*================== FD_ACCEPT ==================*/
- if (networkEvents.lNetworkEvents & FD_ACCEPT) {
- tnet_fd_t fd;
-
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_ACCEPT", transport->description);
-
- if (networkEvents.iErrorCode[FD_ACCEPT_BIT]) {
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
- TNET_PRINT_LAST_ERROR("ACCEPT FAILED.");
- goto done;
- }
-
- /* Accept the connection */
- if ((fd = (tnet_fd_t)WSAAccept(active_socket->fd, NULL, NULL, AcceptCondFunc, (DWORD_PTR)context)) != INVALID_SOCKET) {
- /* Add the new fd to the server context */
- addSocket(fd, transport->master->type, transport, tsk_true, tsk_false, tsk_null);
- if (active_socket->tlshandle) {
- transport_socket_xt* tls_socket;
- if ((tls_socket = getSocket(context, fd))) {
- if (tnet_tls_socket_accept(tls_socket->tlshandle)) {
- tnet_transport_remove_socket(transport, &fd);
- TNET_PRINT_LAST_ERROR("SSL_accept() failed");
- goto done;
- }
- }
- }
- if (WSAEventSelect(fd, context->events[context->count - 1], FD_READ | FD_WRITE | FD_CLOSE) == SOCKET_ERROR) {
- tnet_transport_remove_socket(transport, &fd);
- TNET_PRINT_LAST_ERROR("WSAEventSelect() have failed.");
- goto done;
- }
- TSK_RUNNABLE_ENQUEUE(transport, event_accepted, transport->callback_data, fd);
- }
- else {
- TNET_PRINT_LAST_ERROR("ACCEPT FAILED.");
- goto done;
- }
-
-
-
-
- }
-
- /*================== FD_CONNECT ==================*/
- if (networkEvents.lNetworkEvents & FD_CONNECT) {
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_CONNECT", transport->description);
-
- if (networkEvents.iErrorCode[FD_CONNECT_BIT]) {
- tnet_fd_t fd = active_socket->fd;
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
- tnet_transport_remove_socket(transport, &fd);
- TNET_PRINT_LAST_ERROR("CONNECT FAILED.");
- goto done;
- }
- else {
- TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, active_socket->fd);
- active_socket->connected = 1;
- }
- }
-
-
- /*================== FD_READ ==================*/
- if (networkEvents.lNetworkEvents & FD_READ) {
- DWORD readCount = 0;
- WSABUF wsaBuffer;
-
- /* TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_READ", transport->description); */
-
- /* check whether the socket is paused or not */
- if (active_socket->paused){
- TSK_DEBUG_INFO("Socket is paused");
- goto FD_READ_DONE;
- }
-
- if (networkEvents.iErrorCode[FD_READ_BIT]) {
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
- TNET_PRINT_LAST_ERROR("READ FAILED.");
- goto done;
- }
-
- /* Retrieve the amount of pending data */
- if (tnet_ioctlt(active_socket->fd, FIONREAD, &(wsaBuffer.len)) < 0) {
- TNET_PRINT_LAST_ERROR("IOCTLT FAILED.");
- goto done;
- }
-
- if (!wsaBuffer.len) {
- goto done;
- }
-
- /* Alloc data */
- if (!(wsaBuffer.buf = tsk_calloc(wsaBuffer.len, sizeof(uint8_t)))) {
- goto done;
- }
-
- /* Retrieve the remote address */
- if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
- ret = tnet_getpeername(active_socket->fd, &remote_addr);
- }
-
- /* Receive the waiting data. */
- if (active_socket->tlshandle) {
- int isEncrypted;
- tsk_size_t len = wsaBuffer.len;
- if (!(ret = tnet_tls_socket_recv(active_socket->tlshandle, &wsaBuffer.buf, &len, &isEncrypted))) {
- if (isEncrypted) {
- TSK_FREE(wsaBuffer.buf);
- goto done;
- }
- wsaBuffer.len = (ULONG)len;
- }
- }
- else {
- if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
- ret = WSARecv(active_socket->fd, &wsaBuffer, 1, &readCount, &flags, 0, 0);
- }
- else {
- int len = sizeof(remote_addr);
- ret = WSARecvFrom(active_socket->fd, &wsaBuffer, 1, &readCount, &flags,
- (struct sockaddr*)&remote_addr, &len, 0, 0);
- }
- if (readCount < wsaBuffer.len) {
- wsaBuffer.len = readCount;
- /* wsaBuffer.buf = tsk_realloc(wsaBuffer.buf, readCount); */
- }
- }
-
- if (ret) {
- ret = WSAGetLastError();
- if (ret == WSAEWOULDBLOCK) {
- // Doesn't (always) mean congestion but... another thread is also poll()ing the FD. For example, when TURN session has a reference to the fd.
- TSK_DEBUG_WARN("WSAEWOULDBLOCK error for READ SSESSION");
- }
- else if (ret == WSAECONNRESET && TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)) {
- /* For DGRAM ==> The sent packet gernerated "ICMP Destination/Port unreachable" result. */
- TSK_FREE(wsaBuffer.buf);
- goto done; // ignore and retry.
- }
- else {
- TSK_FREE(wsaBuffer.buf);
-
- removeSocket(index, context);
- TNET_PRINT_LAST_ERROR("WSARecv have failed.");
- goto done;
- }
- }
- else
- {
- tnet_transport_event_t* e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
+ tnet_transport_t *transport = (tnet_transport_t*)param;
+ transport_context_t *context = (transport_context_t*)transport->context;
+ DWORD evt;
+ WSANETWORKEVENTS networkEvents;
+ DWORD flags = 0;
+ int ret;
+
+ struct sockaddr_storage remote_addr = { 0 };
+ WSAEVENT active_event;
+ transport_socket_xt* active_socket;
+ int index;
+
+ TSK_DEBUG_INFO("Starting [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);
+
+ while (TSK_RUNNABLE(transport)->running || TSK_RUNNABLE(transport)->started) {
+ /* Wait for multiple events */
+ if ((evt = WSAWaitForMultipleEvents((DWORD)context->count, context->events, FALSE, WSA_INFINITE, FALSE)) == WSA_WAIT_FAILED) {
+ TNET_PRINT_LAST_ERROR("WSAWaitForMultipleEvents have failed.");
+ goto bail;
+ }
+
+ if (!TSK_RUNNABLE(transport)->running && !TSK_RUNNABLE(transport)->started) {
+ goto bail;
+ }
+
+ /* lock context */
+ tsk_safeobj_lock(context);
+
+ /* Get active event and socket */
+ index = (evt - WSA_WAIT_EVENT_0);
+ active_event = context->events[index];
+ if (!(active_socket = context->sockets[index])) {
+ goto done;
+ }
+
+ /* Get the network events flags */
+ if (WSAEnumNetworkEvents(active_socket->fd, active_event, &networkEvents) == SOCKET_ERROR) {
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
+ TNET_PRINT_LAST_ERROR("WSAEnumNetworkEvents have failed.");
+
+ tsk_safeobj_unlock(context);
+ goto bail;
+ }
+
+ /*================== FD_ACCEPT ==================*/
+ if (networkEvents.lNetworkEvents & FD_ACCEPT) {
+ tnet_fd_t fd;
+
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_ACCEPT", transport->description);
+
+ if (networkEvents.iErrorCode[FD_ACCEPT_BIT]) {
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
+ TNET_PRINT_LAST_ERROR("ACCEPT FAILED.");
+ goto done;
+ }
+
+ /* Accept the connection */
+ if ((fd = (tnet_fd_t)WSAAccept(active_socket->fd, NULL, NULL, AcceptCondFunc, (DWORD_PTR)context)) != INVALID_SOCKET) {
+ /* Add the new fd to the server context */
+ addSocket(fd, transport->master->type, transport, tsk_true, tsk_false, tsk_null);
+ if (active_socket->tlshandle) {
+ transport_socket_xt* tls_socket;
+ if ((tls_socket = getSocket(context, fd))) {
+ if (tnet_tls_socket_accept(tls_socket->tlshandle)) {
+ tnet_transport_remove_socket(transport, &fd);
+ TNET_PRINT_LAST_ERROR("SSL_accept() failed");
+ goto done;
+ }
+ }
+ }
+ if (WSAEventSelect(fd, context->events[context->count - 1], FD_READ | FD_WRITE | FD_CLOSE) == SOCKET_ERROR) {
+ tnet_transport_remove_socket(transport, &fd);
+ TNET_PRINT_LAST_ERROR("WSAEventSelect() have failed.");
+ goto done;
+ }
+ TSK_RUNNABLE_ENQUEUE(transport, event_accepted, transport->callback_data, fd);
+ }
+ else {
+ TNET_PRINT_LAST_ERROR("ACCEPT FAILED.");
+ goto done;
+ }
+
+
+
+
+ }
+
+ /*================== FD_CONNECT ==================*/
+ if (networkEvents.lNetworkEvents & FD_CONNECT) {
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_CONNECT", transport->description);
+
+ if (networkEvents.iErrorCode[FD_CONNECT_BIT]) {
+ tnet_fd_t fd = active_socket->fd;
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, fd);
+ tnet_transport_remove_socket(transport, &fd);
+ TNET_PRINT_LAST_ERROR("CONNECT FAILED.");
+ goto done;
+ }
+ else {
+ TSK_RUNNABLE_ENQUEUE(transport, event_connected, transport->callback_data, active_socket->fd);
+ active_socket->connected = 1;
+ }
+ }
+
+
+ /*================== FD_READ ==================*/
+ if (networkEvents.lNetworkEvents & FD_READ) {
+ DWORD readCount = 0;
+ WSABUF wsaBuffer;
+
+ /* TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_READ", transport->description); */
+
+ /* check whether the socket is paused or not */
+ if (active_socket->paused) {
+ TSK_DEBUG_INFO("Socket is paused");
+ goto FD_READ_DONE;
+ }
+
+ if (networkEvents.iErrorCode[FD_READ_BIT]) {
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
+ TNET_PRINT_LAST_ERROR("READ FAILED.");
+ goto done;
+ }
+
+ /* Retrieve the amount of pending data */
+ if (tnet_ioctlt(active_socket->fd, FIONREAD, &(wsaBuffer.len)) < 0) {
+ TNET_PRINT_LAST_ERROR("IOCTLT FAILED.");
+ goto done;
+ }
+
+ if (!wsaBuffer.len) {
+ goto done;
+ }
+
+ /* Alloc data */
+ if (!(wsaBuffer.buf = tsk_calloc(wsaBuffer.len, sizeof(uint8_t)))) {
+ goto done;
+ }
+
+ /* Retrieve the remote address */
+ if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
+ ret = tnet_getpeername(active_socket->fd, &remote_addr);
+ }
+
+ /* Receive the waiting data. */
+ if (active_socket->tlshandle) {
+ int isEncrypted;
+ tsk_size_t len = wsaBuffer.len;
+ if (!(ret = tnet_tls_socket_recv(active_socket->tlshandle, &wsaBuffer.buf, &len, &isEncrypted))) {
+ if (isEncrypted) {
+ TSK_FREE(wsaBuffer.buf);
+ goto done;
+ }
+ wsaBuffer.len = (ULONG)len;
+ }
+ }
+ else {
+ if (TNET_SOCKET_TYPE_IS_STREAM(transport->master->type)) {
+ ret = WSARecv(active_socket->fd, &wsaBuffer, 1, &readCount, &flags, 0, 0);
+ }
+ else {
+ int len = sizeof(remote_addr);
+ ret = WSARecvFrom(active_socket->fd, &wsaBuffer, 1, &readCount, &flags,
+ (struct sockaddr*)&remote_addr, &len, 0, 0);
+ }
+ if (readCount < wsaBuffer.len) {
+ wsaBuffer.len = readCount;
+ /* wsaBuffer.buf = tsk_realloc(wsaBuffer.buf, readCount); */
+ }
+ }
+
+ if (ret) {
+ ret = WSAGetLastError();
+ if (ret == WSAEWOULDBLOCK) {
+ // Doesn't (always) mean congestion but... another thread is also poll()ing the FD. For example, when TURN session has a reference to the fd.
+ TSK_DEBUG_WARN("WSAEWOULDBLOCK error for READ SSESSION");
+ }
+ else if (ret == WSAECONNRESET && TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type)) {
+ /* For DGRAM ==> The sent packet gernerated "ICMP Destination/Port unreachable" result. */
+ TSK_FREE(wsaBuffer.buf);
+ goto done; // ignore and retry.
+ }
+ else {
+ TSK_FREE(wsaBuffer.buf);
+
+ removeSocket(index, context);
+ TNET_PRINT_LAST_ERROR("WSARecv have failed.");
+ goto done;
+ }
+ }
+ else {
+ tnet_transport_event_t* e = tnet_transport_event_create(event_data, transport->callback_data, active_socket->fd);
transport->bytes_in += wsaBuffer.len;
- e->data = wsaBuffer.buf;
- e->size = wsaBuffer.len;
- e->remote_addr = remote_addr;
+ e->data = wsaBuffer.buf;
+ e->size = wsaBuffer.len;
+ e->remote_addr = remote_addr;
- TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
- }
- FD_READ_DONE:;
- }
+ TSK_RUNNABLE_ENQUEUE_OBJECT_SAFE(TSK_RUNNABLE(transport), e);
+ }
+FD_READ_DONE:
+ ;
+ }
- /*================== FD_WRITE ==================*/
- if (networkEvents.lNetworkEvents & FD_WRITE) {
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_WRITE", transport->description);
+ /*================== FD_WRITE ==================*/
+ if (networkEvents.lNetworkEvents & FD_WRITE) {
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_WRITE", transport->description);
- if (networkEvents.iErrorCode[FD_WRITE_BIT]) {
- TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
- TNET_PRINT_LAST_ERROR("WRITE FAILED.");
- goto done;
- }
- }
+ if (networkEvents.iErrorCode[FD_WRITE_BIT]) {
+ TSK_RUNNABLE_ENQUEUE(transport, event_error, transport->callback_data, active_socket->fd);
+ TNET_PRINT_LAST_ERROR("WRITE FAILED.");
+ goto done;
+ }
+ }
- /*================== FD_CLOSE ==================*/
- if (networkEvents.lNetworkEvents & FD_CLOSE) {
- TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_CLOSE", transport->description);
+ /*================== FD_CLOSE ==================*/
+ if (networkEvents.lNetworkEvents & FD_CLOSE) {
+ TSK_DEBUG_INFO("NETWORK EVENT FOR SERVER [%s] -- FD_CLOSE", transport->description);
- TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, active_socket->fd);
- removeSocket(index, context);
- }
+ TSK_RUNNABLE_ENQUEUE(transport, event_closed, transport->callback_data, active_socket->fd);
+ removeSocket(index, context);
+ }
- /* http://msdn.microsoft.com/en-us/library/ms741690(VS.85).aspx
+ /* http://msdn.microsoft.com/en-us/library/ms741690(VS.85).aspx
- The proper way to reset the state of an event object used with the WSAEventSelect function
- is to pass the handle of the event object to the WSAEnumNetworkEvents function in the hEventObject parameter.
- This will reset the event object and adjust the status of active FD events on the socket in an atomic fashion.
- */
- /* WSAResetEvent(active_event); <== DO NOT USE (see above) */
+ The proper way to reset the state of an event object used with the WSAEventSelect function
+ is to pass the handle of the event object to the WSAEnumNetworkEvents function in the hEventObject parameter.
+ This will reset the event object and adjust the status of active FD events on the socket in an atomic fashion.
+ */
+ /* WSAResetEvent(active_event); <== DO NOT USE (see above) */
- done:
- /* unlock context */
- tsk_safeobj_unlock(context);
- } /* while(transport->running) */
+done:
+ /* unlock context */
+ tsk_safeobj_unlock(context);
+ } /* while(transport->running) */
bail:
- TSK_DEBUG_INFO("Stopped [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);
- return tsk_null;
+ TSK_DEBUG_INFO("Stopped [%s] server with IP {%s} on port {%d} with type {%d}...", transport->description, transport->master->ip, transport->master->port, transport->master->type);
+ return tsk_null;
}
@@ -800,7 +796,7 @@ bail:
tsk_object_t* tnet_transport_context_create()
{
- return tsk_object_new(tnet_transport_context_def_t);
+ return tsk_object_new(tnet_transport_context_def_t);
}
@@ -809,31 +805,30 @@ tsk_object_t* tnet_transport_context_create()
//
static tsk_object_t* transport_context_ctor(tsk_object_t * self, va_list * app)
{
- transport_context_t *context = self;
- if (context){
- tsk_safeobj_init(context);
- }
- return self;
+ transport_context_t *context = self;
+ if (context) {
+ tsk_safeobj_init(context);
+ }
+ return self;
}
static tsk_object_t* transport_context_dtor(tsk_object_t * self)
{
- transport_context_t *context = self;
- if (context) {
- while (context->count) {
- removeSocket(0, context);
- }
- tsk_safeobj_deinit(context);
- }
- return self;
+ transport_context_t *context = self;
+ if (context) {
+ while (context->count) {
+ removeSocket(0, context);
+ }
+ tsk_safeobj_deinit(context);
+ }
+ return self;
}
-static const tsk_object_def_t tnet_transport_context_def_s =
-{
- sizeof(transport_context_t),
- transport_context_ctor,
- transport_context_dtor,
- tsk_null,
+static const tsk_object_def_t tnet_transport_context_def_s = {
+ sizeof(transport_context_t),
+ transport_context_ctor,
+ transport_context_dtor,
+ tsk_null,
};
const tsk_object_def_t *tnet_transport_context_def_t = &tnet_transport_context_def_s;
#endif /* TNET_UNDER_WINDOWS */
diff --git a/tinyNET/src/tnet_types.h b/tinyNET/src/tnet_types.h
index f4b55e2..6edd9cf 100755
--- a/tinyNET/src/tnet_types.h
+++ b/tinyNET/src/tnet_types.h
@@ -7,12 +7,12 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -82,14 +82,13 @@ typedef void tnet_transport_handle_t;
typedef tsk_list_t tnet_interfaces_L_t; /**< List of @ref tnet_interface_t elements*/
typedef tsk_list_t tnet_addresses_L_t; /**< List of @ref tnet_address_t elements*/
-typedef enum tnet_dtls_setup_e
-{
- tnet_dtls_setup_none,
- tnet_dtls_setup_actpass,
- tnet_dtls_setup_active,
- tnet_dtls_setup_passive,
+typedef enum tnet_dtls_setup_e {
+ tnet_dtls_setup_none,
+ tnet_dtls_setup_actpass,
+ tnet_dtls_setup_active,
+ tnet_dtls_setup_passive,
- TNET_DTLS_SETUP_MAX
+ TNET_DTLS_SETUP_MAX
}
tnet_dtls_setup_t;
@@ -103,27 +102,24 @@ typedef enum tnet_proxy_type_e {
}
tnet_proxy_type_t;
-static const char* TNET_DTLS_SETUP_NAMES[TNET_DTLS_SETUP_MAX] =
-{
- "UNKNOWN", "actpass", "active", "passive"
+static const char* TNET_DTLS_SETUP_NAMES[TNET_DTLS_SETUP_MAX] = {
+ "UNKNOWN", "actpass", "active", "passive"
};
-typedef enum tnet_dtls_hash_type_e
-{
- tnet_dtls_hash_type_none,
- tnet_dtls_hash_type_md5,
- tnet_dtls_hash_type_sha1,
- tnet_dtls_hash_type_sha256,
- tnet_dtls_hash_type_sha512,
+typedef enum tnet_dtls_hash_type_e {
+ tnet_dtls_hash_type_none,
+ tnet_dtls_hash_type_md5,
+ tnet_dtls_hash_type_sha1,
+ tnet_dtls_hash_type_sha256,
+ tnet_dtls_hash_type_sha512,
- TNET_DTLS_HASH_TYPE_MAX
+ TNET_DTLS_HASH_TYPE_MAX
}
tnet_dtls_hash_type_t;
// Hash names are case-insensitive but use lower case values because of https://bugzilla.mozilla.org/show_bug.cgi?id=828027
-static const char* TNET_DTLS_HASH_NAMES[TNET_DTLS_HASH_TYPE_MAX] =
-{
- "UNKNOWN", "md5", "sha-1", "sha-256", "sha-512"
+static const char* TNET_DTLS_HASH_NAMES[TNET_DTLS_HASH_TYPE_MAX] = {
+ "UNKNOWN", "md5", "sha-1", "sha-256", "sha-512"
};
#if TNET_UNDER_WINDOWS
@@ -139,22 +135,20 @@ static const char* TNET_DTLS_HASH_NAMES[TNET_DTLS_HASH_TYPE_MAX] =
# if !defined (WC_ERR_INVALID_CHARS)
# define WC_ERR_INVALID_CHARS 0
# endif
- static TNET_INLINE const char* tnet_gai_strerror(int ecode)
- {
- static char aBuff[1024] = {0};
-
- WCHAR *wBuff = gai_strerrorW(ecode);
- int len;
- if((len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wBuff, wcslen(wBuff), aBuff, sizeof(aBuff) - 1, NULL, NULL)) > 0)
- {
- aBuff[len] = '\0';
- }
- else
- {
- aBuff[0] = '\0';
- }
- return aBuff;
- }
+static TNET_INLINE const char* tnet_gai_strerror(int ecode)
+{
+ static char aBuff[1024] = {0};
+
+ WCHAR *wBuff = gai_strerrorW(ecode);
+ int len;
+ if((len = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wBuff, wcslen(wBuff), aBuff, sizeof(aBuff) - 1, NULL, NULL)) > 0) {
+ aBuff[len] = '\0';
+ }
+ else {
+ aBuff[0] = '\0';
+ }
+ return aBuff;
+}
# else
# define tnet_gai_strerror gai_strerrorA
# endif
diff --git a/tinyNET/src/tnet_utils.c b/tinyNET/src/tnet_utils.c
index 64b1ea8..d01facd 100755
--- a/tinyNET/src/tnet_utils.c
+++ b/tinyNET/src/tnet_utils.c
@@ -117,18 +117,18 @@ void tnet_getlasterror(tnet_error_t *error)
{
int err = tnet_geterrno();
memset(*error, 0, sizeof(*error));
-
+
#if TNET_UNDER_WINDOWS_RT
// FormatMessageA Not allowed on Market
static WCHAR wBuff[1024] = { 0 };
FormatMessageW(
- FORMAT_MESSAGE_FROM_SYSTEM,
- tsk_null,
- err,
- 0,
- wBuff,
- sizeof(wBuff)-1,
- tsk_null);
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ tsk_null,
+ err,
+ 0,
+ wBuff,
+ sizeof(wBuff)-1,
+ tsk_null);
WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, wBuff, wcslen(wBuff), *error, sizeof(*error) - 1, NULL, NULL);
#elif TNET_UNDER_WINDOWS
{
@@ -138,13 +138,13 @@ void tnet_getlasterror(tnet_error_t *error)
FormatMessageA
#endif
(
- FORMAT_MESSAGE_FROM_SYSTEM,
- tsk_null,
- err,
- 0,
- *error,
- sizeof(*error) - 1,
- tsk_null);
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ tsk_null,
+ err,
+ 0,
+ *error,
+ sizeof(*error) - 1,
+ tsk_null);
}
#else
strerror_r(err, *error, sizeof(*error));
@@ -175,7 +175,7 @@ int tnet_geterrno()
tnet_interfaces_L_t* tnet_get_interfaces()
{
tnet_interfaces_L_t * ifaces = tsk_list_create();
-
+
#if TNET_UNDER_WINDOWS/*=== WINDOWS XP/VISTA/7/CE===*/
#if TNET_UNDER_WINDOWS_RT
TSK_DEBUG_ERROR("Not implemented on your OS");
@@ -183,101 +183,95 @@ tnet_interfaces_L_t* tnet_get_interfaces()
#else /* !TNET_UNDER_WINDOWS_RT */
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
-
+
PIP_ADAPTER_INFO pAdapterInfo = NULL;
PIP_ADAPTER_INFO pAdapter = NULL;
DWORD dwRetVal = 0;
-
+
ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
pAdapterInfo = (IP_ADAPTER_INFO *)MALLOC(sizeof(IP_ADAPTER_INFO));
- if (pAdapterInfo == NULL)
- {
+ if (pAdapterInfo == NULL) {
TSK_DEBUG_ERROR("Error allocating memory needed to call GetAdaptersinfo.");
goto bail;
}
// Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
- if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
- {
+ if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
FREE(pAdapterInfo);
pAdapterInfo = (IP_ADAPTER_INFO *)MALLOC(ulOutBufLen);
- if (pAdapterInfo == NULL)
- {
+ if (pAdapterInfo == NULL) {
TSK_DEBUG_ERROR("Error allocating memory needed to call GetAdaptersinfo.");
goto bail;
}
}
-
- if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
- {
+
+ if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
pAdapter = pAdapterInfo;
- while (pAdapter)
- {
+ while (pAdapter) {
tnet_interface_t *iface;
-
- if (pAdapter->Type == MIB_IF_TYPE_LOOPBACK){
+
+ if (pAdapter->Type == MIB_IF_TYPE_LOOPBACK) {
continue;
}
-
+
iface = tnet_interface_create(pAdapter->Description, pAdapter->Address, pAdapter->AddressLength);
iface->index = pAdapter->Index;
tsk_list_push_back_data(ifaces, &(iface));
-
+
pAdapter = pAdapter->Next;
}
}
-
- if (pAdapterInfo)
- {
+
+ if (pAdapterInfo) {
FREE(pAdapterInfo);
}
-
-
+
+
#undef MALLOC
#undef FREE
#endif /* !TNET_UNDER_WINDOWS_RT */
-
+
#elif HAVE_IFADDRS_H && HAVE_GETIFADDRS /*=== Using getifaddrs ===*/
-
+
// see http://www.kernel.org/doc/man-pages/online/pages/man3/getifaddrs.3.html
struct ifaddrs *ifaddr = tsk_null, *ifa = tsk_null;
-
+
/* Get interfaces */
- if(getifaddrs(&ifaddr) == -1){
+ if(getifaddrs(&ifaddr) == -1) {
TSK_DEBUG_ERROR("getifaddrs failed and errno= [%d]", tnet_geterrno());
goto bail;
}
-
- for(ifa = ifaddr; ifa; ifa = ifa->ifa_next){
+
+ for(ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
if((ifa->ifa_flags & IFF_LOOPBACK) || !(ifa->ifa_flags & IFF_UP)) {
continue;
}
-
- if(ifa->ifa_addr->sa_family != AF_LINK){
+
+ if(ifa->ifa_addr->sa_family != AF_LINK) {
continue;
}
-
+
#if defined(__linux__) && 0 /* FIXME */
{
struct ifreq ifr;
tnet_fd_t fd = TNET_INVALID_FD;
-
- if((fd = socket(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP)) < 0){
+
+ if((fd = socket(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
TSK_DEBUG_ERROR("Failed to create new DGRAM socket and errno= [%d]", tnet_geterrno());
goto next;
}
-
+
ifr.ifr_addr.sa_family = ifa->ifa_addr->sa_family;
strcpy(ifr.ifr_name, ifa.ifa_name);
- if(tnet_ioctl(fd, SIOCGIFHWADDR, &ifr)<0){
+ if(tnet_ioctl(fd, SIOCGIFHWADDR, &ifr)<0) {
TSK_DEBUG_ERROR("tnet_ioctl(SIOCGIFHWADDR)", tnet_geterrno());
goto next;
}
- else{
+ else {
//sockaddr_dl* sdl = (struct sockaddr_dl *)ifa->ifa_addr;
tnet_interface_t *iface = tnet_interface_create(ifr->ifr_name, ifr->ifr_hwaddr.sa_data, 6);
tsk_list_push_back_data(ifaces, (void**)&(iface));
}
- next:
+next:
tnet_sockfd_close(&fd);
}
#else
@@ -288,66 +282,65 @@ tnet_interfaces_L_t* tnet_get_interfaces()
tsk_list_push_back_data(ifaces, (void**)&(iface));
}
#endif
-
+
}/* for */
-
+
freeifaddrs(ifaddr);
-
+
#else /*=== ANDROID,... --> Using SIOCGIFCONF and SIOCGIFHWADDR ===*/
-
+
tnet_fd_t fd = TNET_INVALID_FD;
char buffer[1024];
struct ifconf ifc;
-
+
struct sockaddr_in *sin;
struct ifreq *ifr;
-
- if((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
+
+ if((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
TSK_DEBUG_ERROR("Failed to create new DGRAM socket and errno= [%d]", tnet_geterrno());
goto done;
}
-
+
ifc.ifc_len = sizeof(buffer);
ifc.ifc_buf = buffer;
-
- if(ioctl(fd, SIOCGIFCONF, &ifc) < 0){
+
+ if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
TSK_DEBUG_ERROR("ioctl(SIOCGIFCONF) failed and errno= [%d]", tnet_geterrno());
goto done;
}
- if(!ifr || !ifc.ifc_req){
+ if(!ifr || !ifc.ifc_req) {
TSK_DEBUG_ERROR("ifr or ifc.ifc_req is null");
goto done;
}
-
- if(!ifr->ifr_name){
+
+ if(!ifr->ifr_name) {
TSK_DEBUG_ERROR("ifr->ifr_name is null");
goto done;
}
-
- for(ifr = ifc.ifc_req; ifr && !tsk_strempty(ifr->ifr_name); ifr++){
+
+ for(ifr = ifc.ifc_req; ifr && !tsk_strempty(ifr->ifr_name); ifr++) {
sin = (struct sockaddr_in *)&(ifr->ifr_addr);
// TODO: IPAddress if needed
- if(/*ioctl(fd, SIOCGIFFLAGS, &ifr) == 0*/1){
- if (!(ifr->ifr_flags & IFF_LOOPBACK) && (ifr->ifr_flags & IFF_UP)){
- if(/*ioctl(fd, SIOCGIFHWADDR, &ifr) == 0*/1){
+ if(/*ioctl(fd, SIOCGIFFLAGS, &ifr) == 0*/1) {
+ if (!(ifr->ifr_flags & IFF_LOOPBACK) && (ifr->ifr_flags & IFF_UP)) {
+ if(/*ioctl(fd, SIOCGIFHWADDR, &ifr) == 0*/1) {
tnet_interface_t *iface = tnet_interface_create(ifr->ifr_name, ifr->ifr_hwaddr.sa_data, 6);
tsk_list_push_back_data(ifaces, (void**)&(iface));
//iface->index = if_nametoindex(ifr->ifr_name);
}
}
}
- else
- {
+ else {
TSK_DEBUG_ERROR("ioctl(SIOCGIFFLAGS) failed and errno= [%d]", tnet_geterrno());
}
}
-
+
done:
tnet_sockfd_close(&fd);
-
-
+
+
#endif
-
+
bail:
return ifaces;
}
@@ -366,69 +359,71 @@ bail:
tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family, tsk_bool_t unicast, tsk_bool_t anycast, tsk_bool_t multicast, tsk_bool_t dnsserver, long if_index)
{
tnet_addresses_L_t *addresses = tsk_list_create();
-
+
#if TNET_UNDER_WINDOWS
#if TNET_UNDER_WINDOWS_RT
TSK_DEBUG_ERROR("Not implemented on your OS");
#else /* !TSK_UNDER_WINDOWS_RT */
-
+
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
-
+
/* Declare and initialize variables */
tnet_ip_t ip;
DWORD dwSize = 0;
DWORD dwRetVal = 0;
-
+
int i = 0;
-
+
// Set the flags to pass to GetAdaptersAddresses
ULONG flags = GAA_FLAG_INCLUDE_PREFIX;
-
+
LPVOID lpMsgBuf = NULL;
-
+
PIP_ADAPTER_ADDRESSES pAddresses = NULL;
ULONG outBufLen = 0;
-
+
PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
PIP_ADAPTER_ANYCAST_ADDRESS pAnycast = NULL;
PIP_ADAPTER_MULTICAST_ADDRESS pMulticast = NULL;
IP_ADAPTER_DNS_SERVER_ADDRESS *pDnServer = NULL;
IP_ADAPTER_PREFIX *pPrefix = NULL;
-
-
+
+
outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen);
-
+
// Make an initial call to GetAdaptersAddresses to get the
// size needed into the outBufLen variable
- if (GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW){
+ if (GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW) {
FREE(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES *)MALLOC(outBufLen);
}
- else goto bail;
-
- if (pAddresses == NULL){
+ else {
+ goto bail;
+ }
+
+ if (pAddresses == NULL) {
TSK_DEBUG_ERROR("Memory allocation failed for IP_ADAPTER_ADDRESSES struct.");
goto bail;
}
-
+
dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen);
-
+
if (dwRetVal == NO_ERROR) {
pCurrAddresses = pAddresses;
- while (pCurrAddresses){
- if ((if_index != -1) && (pCurrAddresses->IfIndex != if_index && pCurrAddresses->Ipv6IfIndex != if_index)){
+ while (pCurrAddresses) {
+ if ((if_index != -1) && (pCurrAddresses->IfIndex != if_index && pCurrAddresses->Ipv6IfIndex != if_index)) {
goto next;
}
- if (pCurrAddresses->OperStatus != IfOperStatusUp){
+ if (pCurrAddresses->OperStatus != IfOperStatusUp) {
goto next;
}
-
+
/* == UNICAST addresses == */
pUnicast = pCurrAddresses->FirstUnicastAddress;
- while (unicast && pUnicast){
+ while (unicast && pUnicast) {
//memset(ip, '\0', sizeof(ip));
tnet_get_sockip(pUnicast->Address.lpSockaddr, &ip);
TSK_DEBUG_INFO("Found local IP address = AdapterName=%s Ip=%s", pCurrAddresses->AdapterName, ip);
@@ -438,13 +433,13 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family, tsk_bool_t unicast,
address->unicast = 1;
tsk_list_push_ascending_data(addresses, &address);
}
-
+
pUnicast = pUnicast->Next;
}
-
+
/* == ANYCAST addresses == */
pAnycast = pCurrAddresses->FirstAnycastAddress;
- while (anycast && pAnycast){
+ while (anycast && pAnycast) {
//memset(ip, '\0', sizeof(ip));
tnet_get_sockip(pAnycast->Address.lpSockaddr, &ip);
{
@@ -453,13 +448,13 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family, tsk_bool_t unicast,
address->anycast = 1;
tsk_list_push_ascending_data(addresses, &address);
}
-
+
pAnycast = pAnycast->Next;
}
-
+
/* == MULTYCAST addresses == */
pMulticast = pCurrAddresses->FirstMulticastAddress;
- while (multicast && pMulticast){
+ while (multicast && pMulticast) {
//memset(ip, '\0', sizeof(ip));
tnet_get_sockip(pMulticast->Address.lpSockaddr, &ip);
{
@@ -468,69 +463,69 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family, tsk_bool_t unicast,
address->multicast = 1;
tsk_list_push_ascending_data(addresses, &address);
}
-
+
pMulticast = pMulticast->Next;
}
-
+
/* == DNS servers == */
pDnServer = pCurrAddresses->FirstDnsServerAddress;
- while (dnsserver && pDnServer){
+ while (dnsserver && pDnServer) {
//memset(ip, '\0', sizeof(ip));
- if (!tnet_get_sockip(pDnServer->Address.lpSockaddr, &ip)){
+ if (!tnet_get_sockip(pDnServer->Address.lpSockaddr, &ip)) {
tnet_address_t *address = tnet_address_create(ip);
address->family = pDnServer->Address.lpSockaddr->sa_family;
address->dnsserver = 1;
tsk_list_push_ascending_data(addresses, &address);
}
-
+
pDnServer = pDnServer->Next;
}
- next:
+next:
pCurrAddresses = pCurrAddresses->Next;
}
}
-
- if (pAddresses){
+
+ if (pAddresses) {
FREE(pAddresses);
}
-
+
#undef MALLOC
#undef FREE
-
- bail :
-
+
+bail :
+
#endif /* !TSK_UNDER_WINDOWS_RT */
-
+
#else /* !TSK_UNDER_WINDOWS (MAC OS X, UNIX, ANDROID ...) */
-
+
tnet_ip_t ip;
#if HAVE_IFADDRS_H && HAVE_GETIFADDRS /*=== Using getifaddrs ===*/
-
+
// see http://www.kernel.org/doc/man-pages/online/pages/man3/getifaddrs.3.html
struct ifaddrs *ifaddr = tsk_null, *ifa = tsk_null;
struct sockaddr *addr;
-
+
/* Get interfaces */
- if(getifaddrs(&ifaddr) == -1){
+ if(getifaddrs(&ifaddr) == -1) {
TSK_DEBUG_ERROR("getifaddrs failed and errno= [%d]", tnet_geterrno());
goto bail;
}
-
+
/* == Unicast addresses == */
- for(ifa = ifaddr; ifa; ifa = ifa->ifa_next){
- if(!ifa->ifa_addr){
+ for(ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
+ if(!ifa->ifa_addr) {
continue;
}
// Skip loopback
if ((ifa->ifa_flags & IFF_LOOPBACK) || !(ifa->ifa_flags & IFF_UP)) {
continue;
}
-
+
// Skip unwanted interface
if (if_index != -1 && if_nametoindex(ifa->ifa_name) != if_index) {
continue;
}
-
+
// Only deal with Unicast address
if (unicast) {
if (family == AF_INET && ifa->ifa_addr->sa_family != AF_INET) {
@@ -542,11 +537,11 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family, tsk_bool_t unicast,
if (ifa->ifa_addr->sa_family != AF_INET && ifa->ifa_addr->sa_family != AF_INET6) {
continue;
}
-
+
// Get the IP string
addr = (struct sockaddr *) ifa->ifa_addr;
tnet_get_sockip(addr, &ip);
-
+
// Push a new address
tnet_address_t *address = tnet_address_create(ip);
address->family = ifa->ifa_addr->sa_family;
@@ -554,81 +549,81 @@ tnet_addresses_L_t* tnet_get_addresses(tnet_family_t family, tsk_bool_t unicast,
tsk_list_push_ascending_data(addresses, (void **) &address);
}
}
-
+
if (ifaddr) {
free(ifaddr);
}
-
+
#else /* ANDROID or any system without getifaddrs */
-
+
tnet_address_t *address;
tnet_fd_t fd = TNET_INVALID_FD;
struct ifconf ifc;
struct ifreq *ifr = 0;
memset(&ifc, 0, sizeof(ifc));
-
- if((fd = socket(family, SOCK_DGRAM, IPPROTO_UDP)) < 0){
+
+ if((fd = socket(family, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
TSK_DEBUG_ERROR("Failed to create new DGRAM socket and errno= [%d]", tnet_geterrno());
goto done;
}
-
- if(ioctl(fd, SIOCGIFCONF, &ifc) < 0){
+
+ if(ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
TSK_DEBUG_ERROR("ioctl(SIOCGIFCONF) failed and errno= [%d]", tnet_geterrno());
goto done;
}
-
+
if (!(ifr = (struct ifreq*) malloc(ifc.ifc_len))) {
TSK_DEBUG_ERROR("Could not malloc ifreq with size =%d", ifc.ifc_len);
goto done;
}
-
+
ifc.ifc_ifcu.ifcu_req = ifr;
if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
TSK_DEBUG_ERROR("ioctl SIOCGIFCONF failed");
goto done;
}
-
+
int i;
- for(i = 0; i < ifc.ifc_len / sizeof(struct ifreq); ++i){
+ for(i = 0; i < ifc.ifc_len / sizeof(struct ifreq); ++i) {
if (unicast) {
-
+
}
// Skip unwanted interface
if (if_index != -1 && ifr->ifr_ifindex != if_index) {
continue;
}
-
+
// Get the IP string
- if(tnet_get_sockip(&ifr[i].ifr_addr, &ip) == 0){
+ if(tnet_get_sockip(&ifr[i].ifr_addr, &ip) == 0) {
// Push a new address
- if((address = tnet_address_create(ip))){
+ if((address = tnet_address_create(ip))) {
address->family = family;
address->unicast = unicast;
tsk_list_push_ascending_data(addresses, (void **) &address);
}
}
}
-
+
done:
TSK_FREE(ifr);
tnet_sockfd_close(&fd);
-
+
#endif /* HAVE_IFADDRS_H && HAVE_GETIFADDRS */
-
+
bail:
-
+
/* == DNS servers == */
- if(dnsserver){
+ if(dnsserver) {
TSK_DEBUG_INFO("Calling 'tnet_dns_resolvconf_parse()' to load DNS servers");
tnet_addresses_L_t * dns_servers;
- if((dns_servers = tnet_dns_resolvconf_parse("/etc/resolv.conf"))){
+ if((dns_servers = tnet_dns_resolvconf_parse("/etc/resolv.conf"))) {
tsk_list_pushback_list(addresses, dns_servers);
TSK_OBJECT_SAFE_FREE(dns_servers);
}
}
-
+
#endif
-
+
return addresses;
}
@@ -637,39 +632,39 @@ bail:
*/
int tnet_get_mac_address(tnet_mac_address* address)
{
- static const tsk_size_t __tnet_mac_address_len = sizeof(tnet_mac_address) / sizeof(uint8_t/*tnet_mac_address[0]*/);
- int ret = -1;
- if (!address) {
- TSK_DEBUG_ERROR("Invalid parameter");
- }
+ static const tsk_size_t __tnet_mac_address_len = sizeof(tnet_mac_address) / sizeof(uint8_t/*tnet_mac_address[0]*/);
+ int ret = -1;
+ if (!address) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ }
#if TNET_UNDER_WINDOWS
# if TNET_UNDER_WINDOWS_RT
- TSK_DEBUG_ERROR("Not implemented on your OS");
+ TSK_DEBUG_ERROR("Not implemented on your OS");
# else /* !TSK_UNDER_WINDOWS_RT */
- {
- IP_ADAPTER_INFO *info = NULL, *pos;
- DWORD size = 0;
- ULONG _ret;
-
- if ((_ret = GetAdaptersInfo(info, &size)) == ERROR_SUCCESS || _ret == ERROR_BUFFER_OVERFLOW) {
- info = (IP_ADAPTER_INFO *)tsk_calloc(size + 1, 1);
- if (info) {
- if ((_ret = GetAdaptersInfo(info, &size)) == ERROR_SUCCESS) {
- UINT i;
- for (pos = info; pos != NULL && ret != 0; pos = pos->Next) {
- if (pos->Type == MIB_IF_TYPE_LOOPBACK && pos->Next) { // skip loopback if we still have items to check
- continue;
- }
- for (i = 0; i < pos->AddressLength && i < __tnet_mac_address_len; ++i) {
- (*address)[i] = pos->Address[i];
- }
- ret = 0;
- }
- }
- }
- TSK_FREE(info);
- }
- }
+ {
+ IP_ADAPTER_INFO *info = NULL, *pos;
+ DWORD size = 0;
+ ULONG _ret;
+
+ if ((_ret = GetAdaptersInfo(info, &size)) == ERROR_SUCCESS || _ret == ERROR_BUFFER_OVERFLOW) {
+ info = (IP_ADAPTER_INFO *)tsk_calloc(size + 1, 1);
+ if (info) {
+ if ((_ret = GetAdaptersInfo(info, &size)) == ERROR_SUCCESS) {
+ UINT i;
+ for (pos = info; pos != NULL && ret != 0; pos = pos->Next) {
+ if (pos->Type == MIB_IF_TYPE_LOOPBACK && pos->Next) { // skip loopback if we still have items to check
+ continue;
+ }
+ for (i = 0; i < pos->AddressLength && i < __tnet_mac_address_len; ++i) {
+ (*address)[i] = pos->Address[i];
+ }
+ ret = 0;
+ }
+ }
+ }
+ TSK_FREE(info);
+ }
+ }
# endif /* TSK_UNDER_WINDOWS_RT */
#elif HAVE_IFADDRS_H && HAVE_GETIFADDRS && HAVE_STRUCT_SOCKADDR_DL
struct ifaddrs *ifaddrs, *ifaddr;
@@ -696,13 +691,13 @@ int tnet_get_mac_address(tnet_mac_address* address)
struct ifreq ifr;
struct ifconf ifc;
char buf[1024];
-
+
tnet_fd_t fd = tnet_soccket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (fd == TNET_INVALID_FD) {
TSK_DEBUG_ERROR("Failed to create socket");
return -1;
}
-
+
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if (ioctl(fd, SIOCGIFCONF, &ifc) != 0) {
@@ -710,10 +705,10 @@ int tnet_get_mac_address(tnet_mac_address* address)
tnet_sockfd_close(&fd);
return -1;
}
-
+
struct ifreq* it = ifc.ifc_req;
const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq));
-
+
for (; it != end; ++it) {
strcpy(ifr.ifr_name, it->ifr_name);
if (ioctl(fd, SIOCGIFFLAGS, &ifr) == 0) {
@@ -732,7 +727,7 @@ int tnet_get_mac_address(tnet_mac_address* address)
}
#endif
- return ret;
+ return ret;
}
/**@ingroup tnet_utils_group
@@ -747,82 +742,76 @@ int tnet_getbestsource(const char* destination, tnet_port_t port, tnet_socket_ty
{
int ret = -1;
struct sockaddr_storage destAddr;
-
+
#if TNET_UNDER_WINDOWS
long dwBestIfIndex = -1;
#endif
#if TNET_UNDER_WINDOWS_RT
Windows::Networking::Connectivity::ConnectionProfile^ profile;
#endif
-
- if (!destination || !source){
+
+ if (!destination || !source) {
TSK_DEBUG_ERROR("Invalid parameter");
goto bail;
}
-
+
memset(*source, '\0', sizeof(*source));
-
+
// special cases for Windows Phone device and emulator
#if TNET_UNDER_WINDOWS_PHONE
- if (tsk_strequals(destination, "127.0.0.1")){
+ if (tsk_strequals(destination, "127.0.0.1")) {
memcpy(*source, "127.0.0.1", 9);
- ret = 0; goto bail;
+ ret = 0;
+ goto bail;
}
- if(tsk_strequals(destination, "::1")){
+ if(tsk_strequals(destination, "::1")) {
memcpy(*source, "::1", 3);
- ret = 0; goto bail;
+ ret = 0;
+ goto bail;
}
#endif
-
- if((ret = tnet_sockaddr_init(destination, port, type, &destAddr))){
+
+ if((ret = tnet_sockaddr_init(destination, port, type, &destAddr))) {
goto bail;
}
-
+
#if TNET_UNDER_WINDOWS_RT /* Windows Phone 8, Surface or any RT */
profile = Windows::Networking::Connectivity::NetworkInformation::GetInternetConnectionProfile();
-
- if (profile != nullptr && profile->NetworkAdapter != nullptr){
+
+ if (profile != nullptr && profile->NetworkAdapter != nullptr) {
TSK_DEBUG_INFO("Network profile IanaInterfaceType = %d", profile->NetworkAdapter->IanaInterfaceType);
Windows::Foundation::Collections::IVectorView<Windows::Networking::HostName^>^ HostNames = Windows::Networking::Connectivity::NetworkInformation::GetHostNames();
-
- if(HostNames->Size > 0)
- {
+
+ if(HostNames->Size > 0) {
Windows::Foundation::Collections::IIterator<Windows::Networking::HostName^>^ HostName = HostNames->First();
- do
- {
+ do {
std::vector<char> CanonicalName = rt_tsk_str_to_native(HostName->Current->CanonicalName);
TSK_DEBUG_INFO("Checking IP address = %s", CanonicalName.data());
- if((TNET_SOCKET_TYPE_IS_IPV4(type) && HostName->Current->IPInformation->PrefixLength->Value > 32) || (TNET_SOCKET_TYPE_IS_IPV6(type) && HostName->Current->IPInformation->PrefixLength->Value > 128))
- {
+ if((TNET_SOCKET_TYPE_IS_IPV4(type) && HostName->Current->IPInformation->PrefixLength->Value > 32) || (TNET_SOCKET_TYPE_IS_IPV6(type) && HostName->Current->IPInformation->PrefixLength->Value > 128)) {
TSK_DEBUG_INFO("Type mismatch - Skiping IP address=%s, IanaInterfaceType=%d, PrefixLength=%d", CanonicalName.data(), HostName->Current->IPInformation->NetworkAdapter->IanaInterfaceType, HostName->Current->IPInformation->PrefixLength->Value);
continue;
}
-
-
- if(HostName->Current->IPInformation != nullptr)
- {
+
+
+ if(HostName->Current->IPInformation != nullptr) {
// http://msdn.microsoft.com/en-us/library/windows/apps/windows.networking.connectivity.networkadapter.networkadapterid.aspx
// HostName->Current->IPInformation->NetworkAdapter->NetworkAdapterId not implemented on WP8
#if WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
tnet_socket_t* ss = tnet_socket_create(CanonicalName.data(), TNET_SOCKET_PORT_ANY, type);
- if(ss)
- {
+ if(ss) {
ret = connect(ss->fd, (const sockaddr*)&destAddr, tnet_get_sockaddr_size((const sockaddr*)&destAddr));
- if(ret && tnet_geterrno() == TNET_ERROR_EAGAIN)
- {
+ if(ret && tnet_geterrno() == TNET_ERROR_EAGAIN) {
ret = tnet_sockfd_waitUntilWritable(ss->fd, 500);
}
TSK_OBJECT_SAFE_FREE(ss);
}
# else
- if(HostName->Current->IPInformation->NetworkAdapter->IanaInterfaceType == profile->NetworkAdapter->IanaInterfaceType)
- {
+ if(HostName->Current->IPInformation->NetworkAdapter->IanaInterfaceType == profile->NetworkAdapter->IanaInterfaceType) {
ret = 0;
}
#endif /* */
-
- if(ret == 0)
- {
+
+ if(ret == 0) {
TSK_DEBUG_INFO("Using best IP address = %s :)", CanonicalName.data());
memcpy(*source, CanonicalName.data(), TSK_MIN(tsk_strlen(CanonicalName.data()), sizeof(*source)));
ret = 0;
@@ -834,30 +823,29 @@ int tnet_getbestsource(const char* destination, tnet_port_t port, tnet_socket_ty
while(HostName->MoveNext());
}
}
- else
- {
+ else {
TSK_DEBUG_ERROR("No network connection available");
}
-
+
#elif TNET_UNDER_WINDOWS /* Windows XP/Vista/7 and Windows Mobile */
- if(GetBestInterfaceEx((struct sockaddr*)&destAddr, &dwBestIfIndex) != NO_ERROR){
+ if(GetBestInterfaceEx((struct sockaddr*)&destAddr, &dwBestIfIndex) != NO_ERROR) {
ret = tnet_geterrno();
TNET_PRINT_LAST_ERROR("GetBestInterfaceEx() failed.");
goto bail;
}
- else{
+ else {
tnet_addresses_L_t* addresses = tsk_null;
const tsk_list_item_t* item;
-
- if (!(addresses = tnet_get_addresses(TNET_SOCKET_TYPE_IS_IPV6(type) ? AF_INET6 : AF_INET, tsk_true, tsk_false, tsk_false, tsk_false, dwBestIfIndex))){
+
+ if (!(addresses = tnet_get_addresses(TNET_SOCKET_TYPE_IS_IPV6(type) ? AF_INET6 : AF_INET, tsk_true, tsk_false, tsk_false, tsk_false, dwBestIfIndex))) {
ret = -2;
TSK_DEBUG_ERROR("Failed to retrieve addresses.");
goto bail;
}
-
- tsk_list_foreach(item, addresses){
+
+ tsk_list_foreach(item, addresses) {
const tnet_address_t* address = item->data;
- if (address && address->ip){
+ if (address && address->ip) {
memcpy(*source, address->ip, tsk_strlen(address->ip) > sizeof(*source) ? sizeof(*source) : tsk_strlen(address->ip));
ret = 0;
break; // First is good for us.
@@ -867,9 +855,9 @@ int tnet_getbestsource(const char* destination, tnet_port_t port, tnet_socket_ty
}
#elif HAVE_NET_ROUTE_H && HAVE_IFADDRS_H && HAVE_GETIFADDRS /* Mac OS X, iPhone, iPod Touch, iPad and Linux family except Android */
/* Thanks to Laurent Etiemble */
-
+
int sdl_index = -1;
-
+
#if HAVE_STRUCT_RT_METRICS && HAVE_STRUCT_SOCKADDR_DL
static int seq = 1234;
char buf[1024];
@@ -882,20 +870,20 @@ int tnet_getbestsource(const char* destination, tnet_port_t port, tnet_socket_ty
struct rt_msghdr *rtm = (struct rt_msghdr *)buf;
struct sockaddr_dl so_ifp;
#endif /* HAVE_STRUCT_RT_METRICS && HAVE_STRUCT_SOCKADDR_DL */
-
+
struct sockaddr_storage so_dst = destAddr;
struct sockaddr *sa = NULL;
struct ifaddrs *ifaddr = 0, *ifa = tsk_null;
tnet_ip_t ip;
-
+
#if HAVE_STRUCT_RT_METRICS && HAVE_STRUCT_SOCKADDR_DL
bzero(rtm, 1024);
cp = (char *)(rtm + 1);
-
+
so_ifp.sdl_index = 0;
so_ifp.sdl_family = AF_LINK;
so_ifp.sdl_len = sizeof(struct sockaddr_dl);
-
+
rtm->rtm_type = RTM_GET;
rtm->rtm_flags = RTF_STATIC | RTF_UP | RTF_GATEWAY;
rtm->rtm_version = RTM_VERSION;
@@ -904,103 +892,104 @@ int tnet_getbestsource(const char* destination, tnet_port_t port, tnet_socket_ty
rtm->rtm_rmx = rt_metrics;
rtm->rtm_inits = rtm_inits;
rtm->rtm_index = 0;
-
+
/** Roundup value to a 4 bytes boundary. */
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
-
+
l = ROUNDUP(so_dst.ss_len);
memcpy(&so_dst, cp, l);
cp += l;
-
+
l = ROUNDUP(so_ifp.sdl_len);
memcpy(&so_ifp, cp, l);
cp += l;
-
+
l = cp - buf;
rtm->rtm_msglen = l;
-
+
s = socket(PF_ROUTE, SOCK_RAW, 0);
if (s < 0) {
// TODO
}
-
+
if ((rlen = write(s, rtm, l)) < 0) {
TSK_DEBUG_INFO("writing to routing socket");
// TODO
}
do {
l = read(s, rtm, 1024);
- } while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid));
-
+ }
+ while (l > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid));
+
/** Advance an address to the closest 4 bytes boundary. */
#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
-
+
if (rtm->rtm_errno == 0 && rtm->rtm_addrs) {
cp = (char *)(rtm + 1);
for (i = 1; i; i <<= 1) {
if (i & rtm->rtm_addrs) {
sa = (struct sockaddr *)cp;
switch (i) {
- case RTA_IFP:
- ifp = (struct sockaddr_dl *) sa;
- break;
+ case RTA_IFP:
+ ifp = (struct sockaddr_dl *) sa;
+ break;
}
ADVANCE(cp, sa);
}
}
}
- if(ifp){
+ if(ifp) {
sdl_index = ifp->sdl_index;
}
#endif /* HAVE_STRUCT_RT_METRICS && HAVE_STRUCT_SOCKADDR_DL */
-
+
/* Get interfaces */
- if(getifaddrs(&ifaddr) == -1){
+ if(getifaddrs(&ifaddr) == -1) {
TNET_PRINT_LAST_ERROR("getifaddrs() failed.");
goto bail;
}
-
- for(ifa = ifaddr; ifa; ifa = ifa->ifa_next){
+
+ for(ifa = ifaddr; ifa; ifa = ifa->ifa_next) {
if ((ifa->ifa_flags & IFF_LOOPBACK) || !(ifa->ifa_flags & IFF_UP)) {
continue;
}
-
+
if (sdl_index != -1 && if_nametoindex(ifa->ifa_name) != sdl_index) {
continue;
}
-
+
if (!ifa->ifa_addr || ifa->ifa_addr->sa_family != destAddr.ss_family) {
continue;
}
-
+
if (destAddr.ss_family == AF_INET6) {
if (IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr) ^
- IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *) &destAddr)->sin6_addr)) {
+ IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *) &destAddr)->sin6_addr)) {
continue;
}
if (IN6_IS_ADDR_SITELOCAL(&((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr) ^
- IN6_IS_ADDR_SITELOCAL(&((struct sockaddr_in6 *) &destAddr)->sin6_addr)) {
+ IN6_IS_ADDR_SITELOCAL(&((struct sockaddr_in6 *) &destAddr)->sin6_addr)) {
continue;
}
}
-
+
tnet_get_sockip((struct sockaddr *) ifa->ifa_addr, &ip);
-
+
memcpy(*source, ip, tsk_strlen(ip) > sizeof(*source) ? sizeof(*source) : tsk_strlen(ip));
ret = 0;
goto bail; // First is good for us.
}
-
-
+
+
#else /* All other systems (Google Android, Unix-Like systems, uLinux, ....) */
TSK_DEBUG_WARN("getbestroute() not supported on this OS");
memcpy(*source,
TNET_SOCKET_TYPE_IS_IPV6(type) ? "::" : "0.0.0.0",
TNET_SOCKET_TYPE_IS_IPV6(type) ? 2 : 7
- );
+ );
#endif
-
+
bail:
return ret;
}
@@ -1021,7 +1010,7 @@ bail:
int tnet_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res)
{
int ret = -1;
- if (hints && (ret = getaddrinfo(node, service, hints, res))){
+ if (hints && (ret = getaddrinfo(node, service, hints, res))) {
TSK_DEBUG_ERROR("getaddrinfo(family=%d, node=%s and service=%s) failed: [%s]", hints->ai_family, node, service, tnet_gai_strerror(ret));
}
return ret;
@@ -1035,7 +1024,7 @@ int tnet_getaddrinfo(const char *node, const char *service, const struct addrinf
**/
void tnet_freeaddrinfo(struct addrinfo *ai)
{
- if (ai){
+ if (ai) {
freeaddrinfo(ai);
}
}
@@ -1048,7 +1037,7 @@ void tnet_freeaddrinfo(struct addrinfo *ai)
*/
int tnet_getsockname(tnet_fd_t fd, struct sockaddr_storage *result)
{
- if (fd > 0 && result){
+ if (fd > 0 && result) {
socklen_t namelen = sizeof(*result);
return getsockname(fd, (struct sockaddr*)result, &namelen);
}
@@ -1057,7 +1046,7 @@ int tnet_getsockname(tnet_fd_t fd, struct sockaddr_storage *result)
int tnet_getpeername(tnet_fd_t fd, struct sockaddr_storage *result)
{
- if (fd > 0 && result){
+ if (fd > 0 && result) {
socklen_t namelen = sizeof(*result);
return getpeername(fd, (struct sockaddr*)result, &namelen);
}
@@ -1072,7 +1061,7 @@ int tnet_getpeername(tnet_fd_t fd, struct sockaddr_storage *result)
tnet_socket_type_t tnet_get_socket_type(tnet_fd_t fd)
{
tnet_socket_type_t type = tnet_socket_type_invalid;
-
+
/*if(fd >0)
{
struct sockaddr_storage ss;
@@ -1088,7 +1077,7 @@ tnet_socket_type_t tnet_get_socket_type(tnet_fd_t fd)
}
}
}*/
-
+
return type;
}
@@ -1102,39 +1091,39 @@ tnet_socket_type_t tnet_get_socket_type(tnet_fd_t fd)
tnet_family_t tnet_get_family(const char* host, tnet_port_t port)
{
tnet_family_t ret = AF_UNSPEC;
- if (host){
+ if (host) {
int status;
tsk_istr_t srv;
struct addrinfo *result = tsk_null;
struct addrinfo hints;
-
+
/* set the port: used as the default service */
- if (port){
+ if (port) {
tsk_itoa(port, &srv);
}
- else{
+ else {
memset(srv, '\0', sizeof(srv));
}
-
+
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
-
+
if ((status = tnet_getaddrinfo(host, srv, &hints, &result))) {
TNET_PRINT_LAST_ERROR("getaddrinfo(%s:%d) failed", host, port);
goto done;
}
-
+
/* Get the First result. */
if (result) {
ret = result->ai_family;
goto done;
}
- done:
+done:
tnet_freeaddrinfo(result);
}
-
+
return ret;
}
@@ -1148,47 +1137,45 @@ tnet_family_t tnet_get_family(const char* host, tnet_port_t port)
int tnet_get_sockip_n_port(const struct sockaddr *addr, tnet_ip_t *ip, tnet_port_t *port)
{
int status = -1;
-
- if (addr->sa_family == AF_INET){
+
+ if (addr->sa_family == AF_INET) {
const struct sockaddr_in *sin = (const struct sockaddr_in *)addr;
- if (port){
+ if (port) {
*port = tnet_ntohs(sin->sin_port);
status = 0;
}
- if (ip){
- if ((status = tnet_getnameinfo((const struct sockaddr*)sin, sizeof(*sin), *ip, sizeof(*ip), 0, 0, NI_NUMERICHOST))){
+ if (ip) {
+ if ((status = tnet_getnameinfo((const struct sockaddr*)sin, sizeof(*sin), *ip, sizeof(*ip), 0, 0, NI_NUMERICHOST))) {
return status;
}
}
}
- else if (addr->sa_family == AF_INET6)
- {
+ else if (addr->sa_family == AF_INET6) {
const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)addr;
#if TNET_UNDER_WINDOWS
int index;
#endif
- if (port){
+ if (port) {
*port = tnet_ntohs(sin6->sin6_port);
status = 0;
}
- if (ip){
- if ((status = tnet_getnameinfo((const struct sockaddr*)sin6, sizeof(*sin6), *ip, sizeof(*ip), 0, 0, NI_NUMERICHOST))){
+ if (ip) {
+ if ((status = tnet_getnameinfo((const struct sockaddr*)sin6, sizeof(*sin6), *ip, sizeof(*ip), 0, 0, NI_NUMERICHOST))) {
return status;
}
-
+
#if TNET_UNDER_WINDOWS
- if ((index = tsk_strindexOf(*ip, tsk_strlen(*ip), "%")) > 0){
+ if ((index = tsk_strindexOf(*ip, tsk_strlen(*ip), "%")) > 0) {
*(*ip + index) = '\0';
}
#endif
}
}
- else
- {
+ else {
TSK_DEBUG_ERROR("Unsupported address family.");
return status;
}
-
+
return status;
}
@@ -1202,24 +1189,24 @@ int tnet_get_sockip_n_port(const struct sockaddr *addr, tnet_ip_t *ip, tnet_port
*/
int tnet_get_peerip_n_port(tnet_fd_t localFD, tnet_ip_t *ip, tnet_port_t *port)
{
- if (port){
+ if (port) {
*port = 0;
}
-
- if (localFD > 0){
+
+ if (localFD > 0) {
int status;
socklen_t len;
struct sockaddr_storage ss;
-
+
len = sizeof(ss);
- if ((status = getpeername(localFD, (struct sockaddr *)&ss, &len))){
+ if ((status = getpeername(localFD, (struct sockaddr *)&ss, &len))) {
TSK_DEBUG_ERROR("TNET_GET_SOCKADDR has failed with status code: %d", status);
return -1;
}
-
+
return tnet_get_sockip_n_port(((struct sockaddr *)&ss), ip, port);
}
-
+
TSK_DEBUG_ERROR("Could not use an invalid socket description.");
return -1;
}
@@ -1230,27 +1217,27 @@ int tnet_get_peerip_n_port(tnet_fd_t localFD, tnet_ip_t *ip, tnet_port_t *port)
* @param getlocal Whether to get local or remote ip and port
* @param ip [out] The IP address of the local socket.
* @param port [out] The port of the local socket.
-
+
* @retval Zero if succeed and non-zero error code otherwise.
*/
int tnet_get_ip_n_port(tnet_fd_t fd, tsk_bool_t getlocal, tnet_ip_t *ip, tnet_port_t *port)
{
- if (port){
+ if (port) {
*port = 0;
}
-
- if (fd > 0){
+
+ if (fd > 0) {
int status;
struct sockaddr_storage ss;
status = getlocal ? tnet_getsockname(fd, &ss) : tnet_getpeername(fd, &ss);
- if (status){
+ if (status) {
TNET_PRINT_LAST_ERROR("TNET_GET_SOCKADDR has failed with status code: %d", status);
return -1;
}
-
+
return tnet_get_sockip_n_port(((struct sockaddr *)&ss), ip, port);
}
-
+
TSK_DEBUG_ERROR("Could not use an invalid socket description.");
return -1;
}
@@ -1310,7 +1297,7 @@ int tnet_get_fd_opened_count(tsk_size_t* count)
char buf[1024];
struct dirent *dp;
DIR *dir;
-
+
if (!count) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
@@ -1457,7 +1444,7 @@ const char *tnet_inet_ntop(int af, const void *src, char *dst, int size)
}
addr.ss_family = AF_INET6;
((struct sockaddr_in6 *)&addr)->sin6_addr = *((struct in6_addr *)src);
-
+
if (tnet_get_sockip((const struct sockaddr *)&addr, &ip)) {
return tsk_null;
}
@@ -1495,29 +1482,29 @@ int tnet_sockfd_waitUntil(tnet_fd_t fd, long timeout, tsk_bool_t writable)
int ret = -1;
fd_set fds;
struct timeval timetowait;
-
- if (fd <= 0){
+
+ if (fd <= 0) {
goto bail;
}
-
- if (timeout >= 0){
+
+ if (timeout >= 0) {
timetowait.tv_sec = (timeout / 1000);
timetowait.tv_usec = (timeout % 1000) * 1000;
}
-
+
FD_ZERO(&fds);
FD_SET(fd, &fds);
-
+
ret = select(fd + 1, writable ? 0 : &fds, writable ? &fds : 0, 0, (timeout >= 0) ? &timetowait : 0);
-
- if (ret == 0){ /* timedout */
+
+ if (ret == 0) { /* timedout */
ret = -2;
}
- else if (ret == 1/* the total number of socket handles that are ready */){
+ else if (ret == 1/* the total number of socket handles that are ready */) {
ret = 0; // Ok
}
//else: error
-
+
bail:
return ret;
}
@@ -1530,21 +1517,21 @@ int tnet_sockfd_joingroup6(tnet_fd_t fd, const char* multiaddr, unsigned iface_i
int ret = -1;
//struct ipv6_mreq mreq6;
//struct sockaddr_storage ss;
-
+
//if((ret = tnet_sockaddr_init(multiaddr, 0, tnet_socket_type_udp_ipv6, &ss)))
//{
// return ret;
//}
-
+
//memcpy(&mreq6.ipv6mr_multiaddr, &((struct sockaddr_in6 *) &ss)->sin6_addr, sizeof(struct in6_addr));
//mreq6.ipv6mr_interface = iface_index;
-
+
//if((ret = setsockopt(fd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (const char*)&mreq6, sizeof(mreq6))))
//{
// TNET_PRINT_LAST_ERROR("Failed to join IPv6 multicast group.");
// return ret;
//}
-
+
return ret;
}
/**@ingroup tnet_utils_group
@@ -1565,7 +1552,7 @@ int tnet_resolve(const char *fqdn, tnet_port_t port, tnet_socket_type_t type, tn
{
struct sockaddr_storage addr;
int ret = tnet_sockaddr_init(fqdn, port, type, &addr);
- if (ret == 0){
+ if (ret == 0) {
return tnet_get_sockip_n_port((const struct sockaddr *)&addr, out_ip, out_port);
}
return ret;
@@ -1581,26 +1568,26 @@ int tnet_sockaddrinfo_init(const char *host, tnet_port_t port, enum tnet_socket_
struct addrinfo *ptr = 0;
struct addrinfo hints;
tsk_istr_t p;
-
+
tsk_itoa(port, &p);
-
+
/* hints address info structure */
memset(&hints, 0, sizeof(hints));
hints.ai_family = TNET_SOCKET_TYPE_IS_IPV46(type) ? AF_UNSPEC : (TNET_SOCKET_TYPE_IS_IPV6(type) ? AF_INET6 : AF_INET);
hints.ai_socktype = TNET_SOCKET_TYPE_IS_STREAM(type) ? SOCK_STREAM : SOCK_DGRAM;
hints.ai_protocol = TNET_SOCKET_TYPE_IS_STREAM(type) ? IPPROTO_TCP : IPPROTO_UDP;
hints.ai_flags = AI_PASSIVE;
-
+
/* Performs getaddrinfo */
- if ((status = tnet_getaddrinfo(host, p, &hints, &result))){
+ if ((status = tnet_getaddrinfo(host, p, &hints, &result))) {
TNET_PRINT_LAST_ERROR("getaddrinfo have failed.");
goto bail;
}
-
+
/* Find our address. */
- for (ptr = result; ptr; ptr = ptr->ai_next){
+ for (ptr = result; ptr; ptr = ptr->ai_next) {
/* Only IPv4 and IPv6 are supported */
- if (ptr->ai_family != AF_INET6 && ptr->ai_family != AF_INET){
+ if (ptr->ai_family != AF_INET6 && ptr->ai_family != AF_INET) {
continue;
}
/* duplicate addrinfo ==> Bad idea
@@ -1611,21 +1598,29 @@ int tnet_sockaddrinfo_init(const char *host, tnet_port_t port, enum tnet_socket_
(*ai)->ai_addrlen = ptr->ai_addrlen;
(*ai)->ai_next = 0;
(*ai)->ai_canonname = 0;*/
-
- if (ai_addr)memcpy(ai_addr, ptr->ai_addr, ptr->ai_addrlen);
- if (ai_family) *ai_family = ptr->ai_family;
- if (ai_socktype) *ai_socktype = ptr->ai_socktype;
- if (ai_protocol) *ai_protocol = ptr->ai_protocol;
-
+
+ if (ai_addr) {
+ memcpy(ai_addr, ptr->ai_addr, ptr->ai_addrlen);
+ }
+ if (ai_family) {
+ *ai_family = ptr->ai_family;
+ }
+ if (ai_socktype) {
+ *ai_socktype = ptr->ai_socktype;
+ }
+ if (ai_protocol) {
+ *ai_protocol = ptr->ai_protocol;
+ }
+
/* We prefer IPv4 but IPv6 can also work */
- if (ptr->ai_family == AF_INET){
+ if (ptr->ai_family == AF_INET) {
break;
}
}
-
+
bail:
tnet_freeaddrinfo(result);
-
+
return status;
}
@@ -1641,13 +1636,13 @@ int tnet_sockaddr_init(const char *host, tnet_port_t port, tnet_socket_type_t ty
{
int status;
struct sockaddr_storage ai_addr;
-
- if ((status = tnet_sockaddrinfo_init(host, port, type, &ai_addr, 0, 0, 0))){
+
+ if ((status = tnet_sockaddrinfo_init(host, port, type, &ai_addr, 0, 0, 0))) {
return status;
}
-
+
memcpy(addr, &ai_addr, sizeof(ai_addr));
-
+
return status;
}
@@ -1665,34 +1660,34 @@ int tnet_sockfd_init(const char *host, tnet_port_t port, enum tnet_socket_type_e
struct sockaddr_storage ai_addr;
int ai_family, ai_socktype, ai_protocol;
*fd = TNET_INVALID_SOCKET;
-
- if ((status = tnet_sockaddrinfo_init(host, port, type, &ai_addr, &ai_family, &ai_socktype, &ai_protocol))){
+
+ if ((status = tnet_sockaddrinfo_init(host, port, type, &ai_addr, &ai_family, &ai_socktype, &ai_protocol))) {
goto bail;
}
-
- if ((*fd = (tnet_fd_t)socket(ai_family, ai_socktype, ai_protocol)) == TNET_INVALID_SOCKET){
+
+ if ((*fd = (tnet_fd_t)socket(ai_family, ai_socktype, ai_protocol)) == TNET_INVALID_SOCKET) {
TNET_PRINT_LAST_ERROR("Failed to create new socket.");
goto bail;
}
-
+
#if TNET_USE_POLL || USE_POLL /* For win32 WSA* function the socket is auto. set to nonblocking mode. */
- if ((status = tnet_sockfd_set_nonblocking(*fd))){
+ if ((status = tnet_sockfd_set_nonblocking(*fd))) {
goto bail;
}
#endif
-
+
#if TNET_HAVE_SS_LEN
if((status = bind(*fd, (const struct sockaddr*)&ai_addr, ai_addr.ss_len)))
#else
- if ((status = bind(*fd, (const struct sockaddr*)&ai_addr, sizeof(ai_addr))))
+ if ((status = bind(*fd, (const struct sockaddr*)&ai_addr, sizeof(ai_addr))))
#endif
- {
- TNET_PRINT_LAST_ERROR("bind have failed.");
- tnet_sockfd_close(fd);
-
- goto bail;
- }
-
+ {
+ TNET_PRINT_LAST_ERROR("bind have failed.");
+ tnet_sockfd_close(fd);
+
+ goto bail;
+ }
+
bail:
return (*fd == TNET_INVALID_SOCKET) ? status : 0;
}
@@ -1705,8 +1700,7 @@ bail:
*/
int tnet_sockfd_set_mode(tnet_fd_t fd, int nonBlocking)
{
- if (fd != TNET_INVALID_FD)
- {
+ if (fd != TNET_INVALID_FD) {
#if TNET_UNDER_WINDOWS
ULONG mode = nonBlocking;
if (ioctlsocket(fd, FIONBIO, &mode))
@@ -1721,15 +1715,15 @@ int tnet_sockfd_set_mode(tnet_fd_t fd, int nonBlocking)
TNET_PRINT_LAST_ERROR("fcntl(F_GETFL) have failed.");
return -1;
}
- if(fcntl(fd, F_SETFL, flags | (nonBlocking ? O_NONBLOCK : ~O_NONBLOCK)) < 0){
+ if(fcntl(fd, F_SETFL, flags | (nonBlocking ? O_NONBLOCK : ~O_NONBLOCK)) < 0) {
TNET_PRINT_LAST_ERROR("fcntl(O_NONBLOCK/O_NONBLOCK) have failed.");
return -1;
}
#endif
-
+
// int on = 1;
// ioctl(fd, FIONBIO, (char *)&on);
-
+
}
return 0;
}
@@ -1775,7 +1769,7 @@ int tnet_sockfd_sendto(tnet_fd_t fd, const struct sockaddr *to, const void* buf,
{
tsk_size_t sent = 0;
int ret = -1;
-
+
if (fd == TNET_INVALID_FD) {
TSK_DEBUG_ERROR("Using invalid FD to send data.");
goto bail;
@@ -1785,7 +1779,7 @@ int tnet_sockfd_sendto(tnet_fd_t fd, const struct sockaddr *to, const void* buf,
ret = -2;
goto bail;
}
-
+
while (sent < size) {
int try_guard = 10;
#if TNET_UNDER_WINDOWS
@@ -1793,13 +1787,13 @@ int tnet_sockfd_sendto(tnet_fd_t fd, const struct sockaddr *to, const void* buf,
DWORD numberOfBytesSent = 0;
wsaBuffer.buf = ((CHAR*)buf) + sent;
wsaBuffer.len = (ULONG)(size - sent);
- try_again:
+try_again:
ret = WSASendTo(fd, &wsaBuffer, 1, &numberOfBytesSent, 0, to, tnet_get_sockaddr_size(to), 0, 0); // returns zero if succeed
if (ret == 0) {
ret = numberOfBytesSent;
}
#else
- try_again:
+try_again:
ret = sendto(fd, (((const uint8_t*)buf) + sent), (size - sent), 0, to, tnet_get_sockaddr_size(to)); // returns number of sent bytes if succeed
#endif
if (ret <= 0) {
@@ -1819,7 +1813,7 @@ int tnet_sockfd_sendto(tnet_fd_t fd, const struct sockaddr *to, const void* buf,
sent += ret;
}
}
-
+
bail:
return (int)((size == sent) ? sent : ret);
}
@@ -1838,12 +1832,12 @@ bail:
int tnet_sockfd_recvfrom(tnet_fd_t fd, void* buf, tsk_size_t size, int flags, struct sockaddr *from)
{
socklen_t fromlen;
-
- if (fd == TNET_INVALID_FD){
+
+ if (fd == TNET_INVALID_FD) {
TSK_DEBUG_ERROR("Using invalid FD to recv data.");
return -1;
}
-
+
fromlen = tnet_get_sockaddr_size(from);
return recvfrom(fd, (char*)buf, (int)size, flags, from, &fromlen);
}
@@ -1861,32 +1855,34 @@ tsk_size_t tnet_sockfd_send(tnet_fd_t fd, const void* buf, tsk_size_t size, int
{
int ret = -1;
tsk_size_t sent = 0;
-
- if (fd == TNET_INVALID_FD){
+
+ if (fd == TNET_INVALID_FD) {
TSK_DEBUG_ERROR("Using invalid FD to send data.");
goto bail;
}
-
- while (sent < size){
- if ((ret = send(fd, (((const char*)buf) + sent), (int)(size - sent), flags)) <= 0){
- if (tnet_geterrno() == TNET_ERROR_WOULDBLOCK){
- if ((ret = tnet_sockfd_waitUntilWritable(fd, TNET_CONNECT_TIMEOUT))){
+
+ while (sent < size) {
+ if ((ret = send(fd, (((const char*)buf) + sent), (int)(size - sent), flags)) <= 0) {
+ if (tnet_geterrno() == TNET_ERROR_WOULDBLOCK) {
+ if ((ret = tnet_sockfd_waitUntilWritable(fd, TNET_CONNECT_TIMEOUT))) {
break;
}
- else continue;
+ else {
+ continue;
+ }
}
- else{
+ else {
TNET_PRINT_LAST_ERROR("send failed");
// Under Windows XP if WSAGetLastError()==WSAEINTR then try to disable both the ICS and the Firewall
// More info about How to disable the ISC: http://support.microsoft.com/?scid=kb%3Ben-us%3B230112&x=6&y=11
goto bail;
}
}
- else{
+ else {
sent += ret;
}
}
-
+
bail:
//return (size == sent) ? sent : ret;
return sent;
@@ -1905,17 +1901,17 @@ bail:
int tnet_sockfd_recv(tnet_fd_t fd, void* buf, tsk_size_t size, int flags)
{
int ret = -1;
-
- if (fd == TNET_INVALID_FD){
+
+ if (fd == TNET_INVALID_FD) {
TSK_DEBUG_ERROR("Using invalid FD to recv data.");
goto bail;
}
-
- if ((ret = (int)recv(fd, (char*)buf, (int)size, flags)) <= 0){
+
+ if ((ret = (int)recv(fd, (char*)buf, (int)size, flags)) <= 0) {
TNET_PRINT_LAST_ERROR("recv failed.");
goto bail;
}
-
+
bail:
return ret;
}
@@ -1929,40 +1925,40 @@ bail:
int tnet_sockfd_connectto(tnet_fd_t fd, const struct sockaddr_storage *to)
{
int status = -1;
-
+
#if TNET_UNDER_WINDOWS
-
- if ((status = WSAConnect(fd, (LPSOCKADDR)to, sizeof(*to), NULL, NULL, NULL, NULL)) == SOCKET_ERROR){
+
+ if ((status = WSAConnect(fd, (LPSOCKADDR)to, sizeof(*to), NULL, NULL, NULL, NULL)) == SOCKET_ERROR) {
status = WSAGetLastError();
- if (status == TNET_ERROR_WOULDBLOCK || status == TNET_ERROR_ISCONN || status == TNET_ERROR_INTR || status == TNET_ERROR_INPROGRESS){
+ if (status == TNET_ERROR_WOULDBLOCK || status == TNET_ERROR_ISCONN || status == TNET_ERROR_INTR || status == TNET_ERROR_INPROGRESS) {
TSK_DEBUG_WARN("TNET_ERROR_WOULDBLOCK/TNET_ERROR_ISCONN/TNET_ERROR_INTR/TNET_ERROR_INPROGRESS -> you should use tnet_sockfd_waitUntilWritable() before trying to send data");
status = 0;
}
- else{
+ else {
TNET_PRINT_LAST_ERROR("WSAConnect have failed");
}
}
-
+
#else /* !TNET_UNDER_WINDOWS */
-
+
#if TNET_HAVE_SS_LEN
if ((status = connect(fd, (struct sockaddr*)to, to->ss_len)))
# else
- if((status = connect(fd, (struct sockaddr*)to, sizeof(*to))))
+ if((status = connect(fd, (struct sockaddr*)to, sizeof(*to))))
# endif
- {
- status = tnet_geterrno();
- if(status == TNET_ERROR_WOULDBLOCK || status == TNET_ERROR_ISCONN || status == TNET_ERROR_INPROGRESS || status == TNET_ERROR_EAGAIN){
- TSK_DEBUG_INFO("TNET_ERROR_WOULDBLOCK/TNET_ERROR_ISCONN/TNET_ERROR_INPROGRESS/TNET_ERROR_EAGAIN ==> use tnet_sockfd_waitUntilWritable.");
- status = 0;
- }
- else{
- TNET_PRINT_LAST_ERROR("connect have failed.");
- }
+ {
+ status = tnet_geterrno();
+ if(status == TNET_ERROR_WOULDBLOCK || status == TNET_ERROR_ISCONN || status == TNET_ERROR_INPROGRESS || status == TNET_ERROR_EAGAIN) {
+ TSK_DEBUG_INFO("TNET_ERROR_WOULDBLOCK/TNET_ERROR_ISCONN/TNET_ERROR_INPROGRESS/TNET_ERROR_EAGAIN ==> use tnet_sockfd_waitUntilWritable.");
+ status = 0;
}
-
+ else {
+ TNET_PRINT_LAST_ERROR("connect have failed.");
+ }
+ }
+
#endif /* TNET_UNDER_WINDOWS */
-
+
return status;
}
@@ -1970,10 +1966,12 @@ int tnet_sockfd_connectto(tnet_fd_t fd, const struct sockaddr_storage *to)
*/
int tnet_sockfd_listen(tnet_fd_t fd, int backlog)
{
- if (fd > 0){
+ if (fd > 0) {
return listen(fd, backlog);
}
- else return -1;
+ else {
+ return -1;
+ }
}
/**@ingroup tnet_utils_group
@@ -1981,11 +1979,11 @@ int tnet_sockfd_listen(tnet_fd_t fd, int backlog)
tnet_fd_t tnet_sockfd_accept(tnet_fd_t fd, struct sockaddr *addr, socklen_t *addrlen)
{
tnet_fd_t ret = TNET_INVALID_FD;
-
- if (fd > 0){
+
+ if (fd > 0) {
ret = (tnet_fd_t)accept(fd, addr, addrlen);
}
-
+
return ret;
}
@@ -1996,7 +1994,7 @@ tnet_fd_t tnet_sockfd_accept(tnet_fd_t fd, struct sockaddr *addr, socklen_t *add
*/
int tnet_sockfd_close(tnet_fd_t *fd)
{
- if (*fd != TNET_INVALID_FD){
+ if (*fd != TNET_INVALID_FD) {
int ret;
#if TNET_UNDER_WINDOWS
ret = closesocket(*fd);
@@ -2025,12 +2023,24 @@ int tnet_sockfd_shutdown(tnet_fd_t fd)
*/
tnet_proxy_type_t tnet_proxy_type_from_string(const char* type)
{
- if (tsk_striequals(type, "http")) return tnet_proxy_type_http;
- else if (tsk_striequals(type, "https")) return tnet_proxy_type_https;
- else if (tsk_striequals(type, "socks4")) return tnet_proxy_type_socks4;
- else if (tsk_striequals(type, "socks4a")) return tnet_proxy_type_socks4a;
- else if (tsk_striequals(type, "socks5")) return tnet_proxy_type_socks5;
- else return tnet_proxy_type_none;
+ if (tsk_striequals(type, "http")) {
+ return tnet_proxy_type_http;
+ }
+ else if (tsk_striequals(type, "https")) {
+ return tnet_proxy_type_https;
+ }
+ else if (tsk_striequals(type, "socks4")) {
+ return tnet_proxy_type_socks4;
+ }
+ else if (tsk_striequals(type, "socks4a")) {
+ return tnet_proxy_type_socks4a;
+ }
+ else if (tsk_striequals(type, "socks5")) {
+ return tnet_proxy_type_socks5;
+ }
+ else {
+ return tnet_proxy_type_none;
+ }
}
/**@ingroup tnet_utils_group
@@ -2038,12 +2048,18 @@ tnet_proxy_type_t tnet_proxy_type_from_string(const char* type)
const char* tnet_proxy_type_to_string(tnet_proxy_type_t type)
{
switch (type) {
- case tnet_proxy_type_http: return "http";
- case tnet_proxy_type_https: return "https";
- case tnet_proxy_type_socks4: return "socks4";
- case tnet_proxy_type_socks4a: return "socks4a";
- case tnet_proxy_type_socks5: return "socks5";
- default: return "none";
+ case tnet_proxy_type_http:
+ return "http";
+ case tnet_proxy_type_https:
+ return "https";
+ case tnet_proxy_type_socks4:
+ return "socks4";
+ case tnet_proxy_type_socks4a:
+ return "socks4a";
+ case tnet_proxy_type_socks5:
+ return "socks5";
+ default:
+ return "none";
}
}
@@ -2092,13 +2108,13 @@ const char* tnet_proxy_type_to_string(tnet_proxy_type_t type)
static tsk_object_t* tnet_interface_ctor(tsk_object_t * self, va_list * app)
{
tnet_interface_t *iface = (tnet_interface_t *)self;
- if (iface){
+ if (iface) {
const char* description = va_arg(*app, const char*);
const void* mac_address = va_arg(*app, const void*);
tsk_size_t mac_address_length = va_arg(*app, tsk_size_t);
-
+
iface->description = tsk_strdup(description);
- if ((iface->mac_address = (uint8_t*)tsk_calloc(mac_address_length, sizeof(uint8_t)))){
+ if ((iface->mac_address = (uint8_t*)tsk_calloc(mac_address_length, sizeof(uint8_t)))) {
memcpy(iface->mac_address, mac_address, mac_address_length);
}
iface->mac_address_length = mac_address_length;
@@ -2109,11 +2125,11 @@ static tsk_object_t* tnet_interface_ctor(tsk_object_t * self, va_list * app)
static tsk_object_t* tnet_interface_dtor(tsk_object_t * self)
{
tnet_interface_t *iface = (tnet_interface_t *)self;
- if (iface){
+ if (iface) {
TSK_FREE(iface->description);
TSK_FREE(iface->mac_address);
}
-
+
return self;
}
@@ -2121,16 +2137,19 @@ static int tnet_interface_cmp(const tsk_object_t *if1, const tsk_object_t *if2)
{
const tnet_interface_t *iface1 = (const tnet_interface_t *)if1;
const tnet_interface_t *iface2 = (const tnet_interface_t *)if2;
-
- if (iface1 && iface2){
+
+ if (iface1 && iface2) {
return tsk_stricmp(iface1->description, iface1->description);
}
- else if (!iface1 && !iface2) return 0;
- else return -1;
+ else if (!iface1 && !iface2) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
}
-static const tsk_object_def_t tnet_interface_def_s =
-{
+static const tsk_object_def_t tnet_interface_def_s = {
sizeof(tnet_interface_t),
tnet_interface_ctor,
tnet_interface_dtor,
@@ -2147,7 +2166,7 @@ const tsk_object_def_t *tnet_interface_def_t = &tnet_interface_def_s;
static tsk_object_t* tnet_address_ctor(tsk_object_t * self, va_list * app)
{
tnet_address_t *address = (tnet_address_t *)self;
- if (address){
+ if (address) {
address->ip = tsk_strdup(va_arg(*app, const char*));
}
return self;
@@ -2156,10 +2175,10 @@ static tsk_object_t* tnet_address_ctor(tsk_object_t * self, va_list * app)
static tsk_object_t* tnet_address_dtor(tsk_object_t * self)
{
tnet_address_t *address = (tnet_address_t *)self;
- if (address){
+ if (address) {
TSK_FREE(address->ip);
}
-
+
return self;
}
@@ -2167,17 +2186,20 @@ static int tnet_address_cmp(const tsk_object_t *_a1, const tsk_object_t *_a2)
{
const tnet_address_t *a1 = (const tnet_address_t *)_a1;
const tnet_address_t *a2 = (const tnet_address_t *)_a2;
-
- if (a1 && a2){
+
+ if (a1 && a2) {
// to have AF_UNSPEC, AF_UNIX, AF_INET, ... first
return (a1->family - a2->family);
}
- else if (!a1 && !a2) return 0;
- else return -1;
+ else if (!a1 && !a2) {
+ return 0;
+ }
+ else {
+ return -1;
+ }
}
-static const tsk_object_def_t tnet_address_def_s =
-{
+static const tsk_object_def_t tnet_address_def_s = {
sizeof(tnet_address_t),
tnet_address_ctor,
tnet_address_dtor,
diff --git a/tinyNET/src/tnet_utils.h b/tinyNET/src/tnet_utils.h
index 6673696..a3abbc9 100755
--- a/tinyNET/src/tnet_utils.h
+++ b/tinyNET/src/tnet_utils.h
@@ -1,18 +1,18 @@
/*
* Copyright (C) 2010-2015 Mamadou DIOP.
-*
+*
* This file is part of Open Source Doubango Framework.
*
* DOUBANGO is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* DOUBANGO is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
* along with DOUBANGO.
*
@@ -40,33 +40,31 @@ TNET_BEGIN_DECLS
/**Interface.
*/
-typedef struct tnet_interface_s
-{
- TSK_DECLARE_OBJECT;
-
- unsigned index;
-
- char* description;
- uint8_t* mac_address;
- tsk_size_t mac_address_length;
+typedef struct tnet_interface_s {
+ TSK_DECLARE_OBJECT;
+
+ unsigned index;
+
+ char* description;
+ uint8_t* mac_address;
+ tsk_size_t mac_address_length;
}
tnet_interface_t;
/**Address.
*/
-typedef struct tnet_address_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_address_s {
+ TSK_DECLARE_OBJECT;
- tnet_family_t family;
+ tnet_family_t family;
- unsigned unicast:1;
- unsigned anycast:1;
- unsigned multicast:1;
- unsigned dnsserver:1;
+ unsigned unicast:1;
+ unsigned anycast:1;
+ unsigned multicast:1;
+ unsigned dnsserver:1;
- char* ip;
+ char* ip;
}
tnet_address_t;
diff --git a/tinyNET/src/turn/tnet_turn.c b/tinyNET/src/turn/tnet_turn.c
index 0f38d02..fc37d68 100755
--- a/tinyNET/src/turn/tnet_turn.c
+++ b/tinyNET/src/turn/tnet_turn.c
@@ -2,19 +2,19 @@
//* Copyright (C) 2010-2011 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-//*
+//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
-//*
+//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
-//*
+//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
@@ -97,7 +97,7 @@
// request->nonce = tsk_strdup(allocation->nonce);
//
// /* Create random transaction id */
-// {
+// {
// tsk_istr_t random;
// tsk_md5digest_t digest;
//
@@ -176,8 +176,8 @@
// tnet_turn_attribute_t *attribute;
// tnet_turn_channel_binding_id_t number;
// uint32_t lifetime;
-//
-//
+//
+//
// channel_binding = va_arg(*app, const tnet_turn_channel_binding_t *);
// number = tnet_htons(channel_binding->id);
// lifetime = tnet_htonl(channel_binding->timeout);
@@ -216,7 +216,7 @@
// tnet_turn_attribute_xpeer_addr_t* xpeer = tsk_object_ref(va_arg(*app, tnet_turn_attribute_xpeer_addr_t *));
// const void* data = va_arg(*app, const void *);
// tsk_size_t size = va_arg(*app, tsk_size_t);
-//
+//
// /*
// draft-ietf-behave-turn-16 - 10.1. Forming a Send Indication
//
@@ -255,7 +255,7 @@
// attribute->xaddress[1] = 0xA1;
// attribute->xaddress[2] = 0x83;
// attribute->xaddress[3] = 0x47;
-//
+//
// tnet_stun_message_add_attribute(request, (tnet_stun_attr_t**)&attribute);
//
// /*if((attribute = tnet_turn_attribute_even_port_create(context->enable_evenport)))
@@ -293,7 +293,7 @@
// { /* First time we get a nonce */
// tsk_strupdate(&allocation->nonce, nonce);
// tsk_strupdate(&allocation->realm, realm);
-//
+//
// /* Delete the message and response before retrying*/
// TSK_OBJECT_SAFE_FREE(response);
// TSK_OBJECT_SAFE_FREE(request);
@@ -347,7 +347,7 @@
// TSK_OBJECT_SAFE_FREE(response);
// }
// }
-//
+//
// TSK_OBJECT_SAFE_FREE(request);
// return ret;
//}
@@ -357,12 +357,12 @@
//tnet_turn_allocation_id_t tnet_turn_allocate(const tnet_nat_context_t* nat_context, const tnet_fd_t localFD, tnet_socket_type_t socket_type)
//{
// tnet_turn_allocation_id_t id = TNET_TURN_INVALID_ALLOCATION_ID;
-//
+//
// if(nat_context){
// int ret;
// tnet_turn_allocation_t* allocation = tnet_turn_allocation_create(localFD, nat_context->socket_type, nat_context->server_address, nat_context->server_port, nat_context->username, nat_context->password);
// allocation->software = tsk_strdup(nat_context->software);
-//
+//
// if((ret = tnet_turn_send_request(nat_context, allocation, tnet_turn_create_request_allocate))){
// TSK_DEBUG_ERROR("TURN allocation failed with error code:%d.", ret);
// TSK_OBJECT_SAFE_FREE(allocation);
@@ -422,9 +422,9 @@
//
// if(nat_context && allocation){
// int ret;
-//
+//
// channel_binding = tnet_turn_channel_binding_create(allocation);
-//
+//
// if(channel_binding){
// if(((struct sockaddr*)peer)->sa_family == AF_INET){
// struct sockaddr_in *sin = ((struct sockaddr_in*)peer);
@@ -433,7 +433,7 @@
// channel_binding->xpeer = tnet_turn_attribute_xpeer_addr_create_null();
// channel_binding->xpeer->family = stun_ipv4;
// channel_binding->xpeer->xport = ((sin->sin_port) ^ tnet_htons(0x2112));
-//
+//
// _sin_addr = tnet_htonl_2(&sin->sin_addr) ^tnet_htonl(kStunMagicCookieLong);
// memcpy(channel_binding->xpeer->xaddress, &_sin_addr, sizeof(_sin_addr));
// }
@@ -453,7 +453,7 @@
// if((ret = tnet_turn_send_request(nat_context, allocation, tnet_turn_create_request_channel_bind, channel_binding))){
// TSK_DEBUG_ERROR("TURN (CHANNEL-BIND) failed with error code:%d.", ret);
// TSK_OBJECT_SAFE_FREE(channel_binding);
-//
+//
// goto bail;
// }
// else{
@@ -566,8 +566,8 @@
//{
// tnet_turn_channel_binding_t *channel_binding = self;
// if(channel_binding){
-// static tnet_turn_channel_binding_id_t __allocation_unique_id = 0x4000; /* 0x4000 through 0x7FFF */
-//
+// static tnet_turn_channel_binding_id_t __allocation_unique_id = 0x4000; /* 0x4000 through 0x7FFF */
+//
// channel_binding->id = __allocation_unique_id++;
// channel_binding->allocation = va_arg(*app, const tnet_turn_allocation_t *);
// channel_binding->timeout = TNET_TURN_CHANBIND_TIMEOUT_DEFAULT; /* 10 minutes as per draft-ietf-behave-turn-16 subclause 11 */
@@ -580,21 +580,21 @@
//}
//
//static tsk_object_t* tnet_turn_channel_binding_dtor(tsk_object_t * self)
-//{
+//{
// tnet_turn_channel_binding_t *channel_binding = self;
// if(channel_binding){
// TSK_OBJECT_SAFE_FREE(channel_binding->xpeer);
// }
-//
+//
// return self;
//}
//
-//static const tsk_object_def_t tnet_turn_channel_binding_def_s =
+//static const tsk_object_def_t tnet_turn_channel_binding_def_s =
//{
// sizeof(tnet_turn_channel_binding_t),
-// tnet_turn_channel_binding_ctor,
+// tnet_turn_channel_binding_ctor,
// tnet_turn_channel_binding_dtor,
-// tsk_null,
+// tsk_null,
//};
//const tsk_object_def_t *tnet_turn_channel_binding_def_t = &tnet_turn_channel_binding_def_s;
//
@@ -611,21 +611,21 @@
//}
//
//static tsk_object_t* tnet_turn_permission_dtor(tsk_object_t * self)
-//{
+//{
// tnet_turn_permission_t *permission = self;
// if(permission){
// TSK_OBJECT_SAFE_FREE(permission->xpeer);
// }
-//
+//
// return self;
//}
//
-//static const tsk_object_def_t tnet_turn_permission_def_s =
+//static const tsk_object_def_t tnet_turn_permission_def_s =
//{
// sizeof(tnet_turn_permission_t),
-// tnet_turn_permission_ctor,
+// tnet_turn_permission_ctor,
// tnet_turn_permission_dtor,
-// tsk_null,
+// tsk_null,
//};
//const tsk_object_def_t *tnet_turn_permission_def_t = &tnet_turn_permission_def_s;
//
@@ -639,7 +639,7 @@
// tnet_turn_allocation_t *allocation = self;
// if(allocation){
// static tnet_turn_allocation_id_t __allocation_unique_id = 0;
-//
+//
// const char* server_address;
// tnet_port_t server_port;
//
@@ -647,7 +647,7 @@
//
// allocation->localFD = va_arg(*app, tnet_fd_t);
// allocation->socket_type = va_arg(*app, tnet_socket_type_t);
-//
+//
// server_address = va_arg(*app, const char*);
//#if defined(__GNUC__)
// server_port = (tnet_port_t)va_arg(*app, unsigned);
@@ -668,7 +668,7 @@
//}
//
//static tsk_object_t* tnet_turn_allocation_dtor(tsk_object_t * self)
-//{
+//{
// tnet_turn_allocation_t *allocation = self;
// if(allocation){
// TSK_FREE(allocation->relay_address);
@@ -679,23 +679,23 @@
// TSK_FREE(allocation->nonce);
//
// TSK_FREE(allocation->software);
-//
+//
// TSK_OBJECT_SAFE_FREE(allocation->xmaddr);
// TSK_OBJECT_SAFE_FREE(allocation->maddr);
//
// TSK_OBJECT_SAFE_FREE(allocation->channel_bindings);
// TSK_OBJECT_SAFE_FREE(allocation->permissions);
// }
-//
+//
// return self;
//}
//
-//static const tsk_object_def_t tnet_turn_allocation_def_s =
+//static const tsk_object_def_t tnet_turn_allocation_def_s =
//{
// sizeof(tnet_turn_allocation_t),
-// tnet_turn_allocation_ctor,
+// tnet_turn_allocation_ctor,
// tnet_turn_allocation_dtor,
-// tsk_null,
+// tsk_null,
//};
//const tsk_object_def_t *tnet_turn_allocation_def_t = &tnet_turn_allocation_def_s;
//
diff --git a/tinyNET/src/turn/tnet_turn.h b/tinyNET/src/turn/tnet_turn.h
index af3a5e4..f1c050e 100755
--- a/tinyNET/src/turn/tnet_turn.h
+++ b/tinyNET/src/turn/tnet_turn.h
@@ -2,19 +2,19 @@
//* Copyright (C) 2010-2011 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-//*
+//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
-//*
+//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
-//*
+//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
@@ -113,15 +113,15 @@
//typedef struct tnet_turn_allocation_s
//{
// TSK_DECLARE_OBJECT;
-//
+//
// tnet_turn_allocation_id_t id; /**< Unique id. */
-//
+//
// char* relay_address; /**< the relayed transport address */
// //! Server reflexive address of the local socket(STUN1 as per RFC 3489).
// tnet_stun_attribute_mapped_addr_t *maddr;
// //! XORed server reflexive address (STUN2 as per RFC 5389).
// tnet_stun_attribute_xmapped_addr_t *xmaddr;
-//
+//
// /* 5-tuple */
// tnet_fd_t localFD;
// tnet_socket_type_t socket_type;
diff --git a/tinyNET/src/turn/tnet_turn_attribute.c b/tinyNET/src/turn/tnet_turn_attribute.c
index 719f926..5dc3ee3 100755
--- a/tinyNET/src/turn/tnet_turn_attribute.c
+++ b/tinyNET/src/turn/tnet_turn_attribute.c
@@ -2,19 +2,19 @@
//* Copyright (C) 2010-2011 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-//*
+//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
-//*
+//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
-//*
+//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
@@ -116,7 +116,7 @@
//
// /* Attribute Value
// */
-//
+//
// switch(type)
// {
// /* draft-ietf-behave-turn-16 - 14.1. CHANNEL-NUMBER */
@@ -176,7 +176,7 @@
// TSK_DEBUG_ERROR("==> NOT IMPLEMENTED");
// break;
// }
-//
+//
// /* draft-ietf-behave-turn-16 - 14.9. RESERVATION-TOKEN */
// case stun_reservation_token:
// {
@@ -296,7 +296,7 @@
// TSK_DEBUG_ERROR("SERIALIZE:TOKEN ==> NOT IMPLEMENTED");
// return -3;
// }
-//
+//
// default: break;
// }
//
@@ -324,8 +324,8 @@
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_channelnum_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_channelnum_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_channelnum_t *attribute = self;
// if(attribute){
// }
@@ -357,8 +357,8 @@
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_lifetime_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_lifetime_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_lifetime_t *attribute = self;
// if(attribute){
// }
@@ -386,7 +386,7 @@
// if(attribute){
// const void *payload = va_arg(*app, const void*);
// tsk_size_t payload_size = va_arg(*app, tsk_size_t);
-//
+//
// if(payload && payload_size){
// }
// TNET_STUN_ATTRIBUTE(attribute)->type = stun_xor_peer_address;
@@ -395,8 +395,8 @@
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_xpeer_addr_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_xpeer_addr_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_xpeer_addr_t *attribute = self;
// if(attribute){
// }
@@ -432,8 +432,8 @@
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_data_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_data_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_data_t *attribute = self;
// if(attribute){
// TSK_OBJECT_SAFE_FREE(attribute->value);
@@ -466,7 +466,7 @@
//
// TNET_STUN_ATTRIBUTE(attribute)->type = stun_xor_relayed_address;
// TNET_STUN_ATTRIBUTE(attribute)->length = payload_size;
-//
+//
// attribute->family = (tnet_stun_addr_family_t)(*(payloadPtr++));
//
// attribute->xport = tnet_ntohs_2(payloadPtr);
@@ -475,7 +475,7 @@
//
// { /*=== Compute IP address */
// tsk_size_t addr_size = (attribute->family == stun_ipv6) ? 16 : (attribute->family == stun_ipv4 ? 4 : 0);
-// if(addr_size){
+// if(addr_size){
// tsk_size_t i;
// uint32_t addr;
//
@@ -489,14 +489,14 @@
// else{
// TSK_DEBUG_ERROR("UNKNOWN FAMILY [%u].", attribute->family);
// }
-// }
+// }
// }
// }
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_xrelayed_addr_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_xrelayed_addr_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_xrelayed_addr_t *attribute = self;
// if(attribute){
// }
@@ -528,8 +528,8 @@
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_even_port_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_even_port_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_even_port_t *attribute = self;
// if(attribute){
// }
@@ -561,8 +561,8 @@
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_reqtrans_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_reqtrans_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_reqtrans_t *attribute = self;
// if(attribute){
// }
@@ -594,8 +594,8 @@
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_dontfrag_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_dontfrag_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_dontfrag_t *attribute = self;
// if(attribute){
// }
@@ -628,8 +628,8 @@
// return self;
//}
//
-//static tsk_object_t* tnet_turn_attribute_restoken_dtor(tsk_object_t * self)
-//{
+//static tsk_object_t* tnet_turn_attribute_restoken_dtor(tsk_object_t * self)
+//{
// tnet_turn_attribute_restoken_t *attribute = self;
// if(attribute){
// }
diff --git a/tinyNET/src/turn/tnet_turn_attribute.h b/tinyNET/src/turn/tnet_turn_attribute.h
index 127116c..998379e 100755
--- a/tinyNET/src/turn/tnet_turn_attribute.h
+++ b/tinyNET/src/turn/tnet_turn_attribute.h
@@ -2,19 +2,19 @@
//* Copyright (C) 2010-2011 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-//*
+//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
-//*
+//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
-//*
+//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
@@ -117,7 +117,7 @@
//typedef struct tnet_turn_attribute_even_port_s
//{
// TNET_STUN_DECLARE_ATTRIBUTE;
-//
+//
///*
// 0 1 2 3 4 5 6 7
// +-+-+-+-+-+-+-+-+
@@ -136,7 +136,7 @@
//typedef struct tnet_turn_attribute_reqtrans_s
//{
// TNET_STUN_DECLARE_ATTRIBUTE;
-///*
+///*
// draft-ietf-behave-turn-16 - 14.7. REQUESTED-TRANSPORT
// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
diff --git a/tinyNET/src/turn/tnet_turn_message.c b/tinyNET/src/turn/tnet_turn_message.c
index 989fd2b..b0eff46 100755
--- a/tinyNET/src/turn/tnet_turn_message.c
+++ b/tinyNET/src/turn/tnet_turn_message.c
@@ -2,19 +2,19 @@
//* Copyright (C) 2010-2011 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-//*
+//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
-//*
+//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
-//*
+//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
@@ -144,20 +144,20 @@
//}
//
//static tsk_object_t* tnet_turn_channel_data_dtor(tsk_object_t * self)
-//{
+//{
// tnet_turn_channel_data_t *message = self;
// if(message){
// TSK_FREE(message->data);
// }
-//
+//
// return self;
//}
//
-//static const tsk_object_def_t tnet_turn_channel_data_def_s =
+//static const tsk_object_def_t tnet_turn_channel_data_def_s =
//{
// sizeof(tnet_turn_channel_data_t),
-// tnet_turn_channel_data_ctor,
+// tnet_turn_channel_data_ctor,
// tnet_turn_channel_data_dtor,
-// tsk_null,
+// tsk_null,
//};
//const tsk_object_def_t *tnet_turn_channel_data_def_t = &tnet_turn_channel_data_def_s;
diff --git a/tinyNET/src/turn/tnet_turn_message.h b/tinyNET/src/turn/tnet_turn_message.h
index c518366..c98d4f0 100755
--- a/tinyNET/src/turn/tnet_turn_message.h
+++ b/tinyNET/src/turn/tnet_turn_message.h
@@ -2,19 +2,19 @@
//* Copyright (C) 2010-2011 Mamadou Diop.
//*
//* Contact: Mamadou Diop <diopmamadou(at)doubango[dot]org>
-//*
+//*
//* This file is part of Open Source Doubango Framework.
//*
//* DOUBANGO is free software: you can redistribute it and/or modify
//* it under the terms of the GNU General Public License as published by
//* the Free Software Foundation, either version 3 of the License, or
//* (at your option) any later version.
-//*
+//*
//* DOUBANGO is distributed in the hope that it will be useful,
//* but WITHOUT ANY WARRANTY; without even the implied warranty of
//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//* GNU General Public License for more details.
-//*
+//*
//* You should have received a copy of the GNU General Public License
//* along with DOUBANGO.
//*
diff --git a/tinyNET/src/turn/tnet_turn_session.c b/tinyNET/src/turn/tnet_turn_session.c
index e131dbc..801f01a 100755
--- a/tinyNET/src/turn/tnet_turn_session.c
+++ b/tinyNET/src/turn/tnet_turn_session.c
@@ -45,143 +45,141 @@
typedef tnet_stun_pkt_t tnet_turn_pkt_t;
-typedef struct tnet_turn_peer_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_turn_peer_s {
+ TSK_DECLARE_OBJECT;
- tnet_turn_peer_id_t id;
+ tnet_turn_peer_id_t id;
- uint16_t u_chan_num;
- uint32_t u_conn_id; // rfc6062 - 6.2.1. CONNECTION-ID, For streams only
- tnet_fd_t conn_fd; // Connected FD: used for Streams only
+ uint16_t u_chan_num;
+ uint32_t u_conn_id; // rfc6062 - 6.2.1. CONNECTION-ID, For streams only
+ tnet_fd_t conn_fd; // Connected FD: used for Streams only
- tnet_stun_addr_t addr_ip;
- char* p_addr_ip;
- uint16_t u_addr_port;
- tsk_bool_t b_ipv6;
- tsk_bool_t b_stream_connected;
- tsk_buffer_t *p_stream_buff_in;
+ tnet_stun_addr_t addr_ip;
+ char* p_addr_ip;
+ uint16_t u_addr_port;
+ tsk_bool_t b_ipv6;
+ tsk_bool_t b_stream_connected;
+ tsk_buffer_t *p_stream_buff_in;
tsk_buffer_t *p_stream_buff_out;
-
- tnet_stun_state_t e_createperm_state;
- tnet_stun_state_t e_chanbind_state;
- tnet_stun_state_t e_connect_state;
- tnet_stun_state_t e_connbind_state;
-
- tnet_turn_pkt_t* p_pkt_createperm;
- tnet_stun_pkt_t* p_pkt_sendind;
- tnet_stun_pkt_t* p_pkt_chanbind;
- tnet_stun_pkt_t* p_pkt_connect; // For streams only
- tnet_stun_pkt_t* p_pkt_connbind; // For streams only
-
- struct {
- struct {
- struct {
- tsk_timer_id_t id;
- uint64_t u_timeout;
- } createperm;
- struct {
- tsk_timer_id_t id;
- uint64_t u_timeout;
- } chanbind;
- } fresh; // schedule refresh
- struct {
- struct {
- tsk_timer_id_t id;
- uint64_t u_timeout;
- } createperm;
- struct {
- tsk_timer_id_t id;
- uint64_t u_timeout;
- } chanbind;
- } rtt; // retransmit (UDP only, to deal with pkt loss)
- } timer;
+
+ tnet_stun_state_t e_createperm_state;
+ tnet_stun_state_t e_chanbind_state;
+ tnet_stun_state_t e_connect_state;
+ tnet_stun_state_t e_connbind_state;
+
+ tnet_turn_pkt_t* p_pkt_createperm;
+ tnet_stun_pkt_t* p_pkt_sendind;
+ tnet_stun_pkt_t* p_pkt_chanbind;
+ tnet_stun_pkt_t* p_pkt_connect; // For streams only
+ tnet_stun_pkt_t* p_pkt_connbind; // For streams only
+
+ struct {
+ struct {
+ struct {
+ tsk_timer_id_t id;
+ uint64_t u_timeout;
+ } createperm;
+ struct {
+ tsk_timer_id_t id;
+ uint64_t u_timeout;
+ } chanbind;
+ } fresh; // schedule refresh
+ struct {
+ struct {
+ tsk_timer_id_t id;
+ uint64_t u_timeout;
+ } createperm;
+ struct {
+ tsk_timer_id_t id;
+ uint64_t u_timeout;
+ } chanbind;
+ } rtt; // retransmit (UDP only, to deal with pkt loss)
+ } timer;
}
tnet_turn_peer_t;
typedef tsk_list_t tnet_turn_peers_L_t;
-typedef struct tnet_turn_session_s
-{
- TSK_DECLARE_OBJECT;
+typedef struct tnet_turn_session_s {
+ TSK_DECLARE_OBJECT;
+
+ tsk_bool_t b_prepared;
+ tsk_bool_t b_started;
+ tsk_bool_t b_stopping;
+ enum tnet_stun_state_e e_alloc_state;
+ enum tnet_stun_state_e e_refresh_state;
- tsk_bool_t b_prepared;
- tsk_bool_t b_started;
- tsk_bool_t b_stopping;
- enum tnet_stun_state_e e_alloc_state;
- enum tnet_stun_state_e e_refresh_state;
-
- enum tnet_turn_transport_e e_req_transport;
+ enum tnet_turn_transport_e e_req_transport;
- uint32_t u_lifetime_alloc_in_sec;
+ uint32_t u_lifetime_alloc_in_sec;
- tnet_turn_pkt_t* p_pkt_alloc;
- tnet_stun_pkt_t* p_pkt_refresh;
+ tnet_turn_pkt_t* p_pkt_alloc;
+ tnet_stun_pkt_t* p_pkt_refresh;
- void* p_buff_send_ptr;
- tsk_size_t u_buff_send_size;
+ void* p_buff_send_ptr;
+ tsk_size_t u_buff_send_size;
- void* p_buff_chandata_ptr;
- tsk_size_t u_buff_chandata_size;
+ void* p_buff_chandata_ptr;
+ tsk_size_t u_buff_chandata_size;
- char* p_rel_ip;
- uint16_t u_rel_port;
- tsk_bool_t b_rel_ipv6;
+ char* p_rel_ip;
+ uint16_t u_rel_port;
+ tsk_bool_t b_rel_ipv6;
+
+ char* p_srflx_ip;
+ uint16_t u_srflx_port;
+ tsk_bool_t b_srflx_ipv6;
- char* p_srflx_ip;
- uint16_t u_srflx_port;
- tsk_bool_t b_srflx_ipv6;
-
struct {
tsk_bool_t auto_detect;
struct tnet_proxyinfo_s* info;
}
proxy;
- struct {
- char* path_priv;
- char* path_pub;
- char* path_ca;
- tsk_bool_t verify;
- } ssl;
-
- struct {
- char* p_usr_name;
- char* p_pwd;
- } cred;
-
- struct {
- tnet_turn_session_callback_f f_fun;
- struct tnet_turn_session_event_xs e;
- } cb;
-
- struct {
- tsk_timer_manager_handle_t *p_mgr;
- tsk_timer_id_t u_timer_id_refresh; // To refresh Alloc (Send Refresh Indication)
- struct {
- struct {
- tsk_timer_id_t id;
- uint64_t u_timeout;
- } alloc;
- struct {
- tsk_timer_id_t id;
- uint64_t u_timeout;
- } refresh;
- } rtt; // retransmit (UDP only)
- } timer;
-
- tnet_socket_t* p_lcl_sock;
- char* p_srv_host;
- uint16_t u_srv_port;
- tsk_bool_t b_stream_connected;
+ struct {
+ char* path_priv;
+ char* path_pub;
+ char* path_ca;
+ tsk_bool_t verify;
+ } ssl;
+
+ struct {
+ char* p_usr_name;
+ char* p_pwd;
+ } cred;
+
+ struct {
+ tnet_turn_session_callback_f f_fun;
+ struct tnet_turn_session_event_xs e;
+ } cb;
+
+ struct {
+ tsk_timer_manager_handle_t *p_mgr;
+ tsk_timer_id_t u_timer_id_refresh; // To refresh Alloc (Send Refresh Indication)
+ struct {
+ struct {
+ tsk_timer_id_t id;
+ uint64_t u_timeout;
+ } alloc;
+ struct {
+ tsk_timer_id_t id;
+ uint64_t u_timeout;
+ } refresh;
+ } rtt; // retransmit (UDP only)
+ } timer;
+
+ tnet_socket_t* p_lcl_sock;
+ char* p_srv_host;
+ uint16_t u_srv_port;
+ tsk_bool_t b_stream_connected;
tsk_buffer_t* p_stream_buff_out; // data pending until the socket is connected
- tsk_bool_t b_stream_error; // Unrecoverable error occured
- tsk_buffer_t *p_stream_buff_in;
- struct sockaddr_storage srv_addr;
- struct tnet_transport_s* p_transport;
+ tsk_bool_t b_stream_error; // Unrecoverable error occured
+ tsk_buffer_t *p_stream_buff_in;
+ struct sockaddr_storage srv_addr;
+ struct tnet_transport_s* p_transport;
- tnet_turn_peers_L_t* p_list_peers;
+ tnet_turn_peers_L_t* p_list_peers;
- TSK_DECLARE_SAFEOBJ;
+ TSK_DECLARE_SAFEOBJ;
}
tnet_turn_session_t;
@@ -207,87 +205,99 @@ static int _tnet_turn_peer_create(const char* pc_peer_ip, uint16_t u_peer_port,
static int _tnet_turn_peer_find_by_xpeer(const tnet_turn_peers_L_t* pc_peers, const tnet_stun_attr_address_t* pc_xpeer, const tnet_turn_peer_t **ppc_peer);
/*** PREDICATES ***/
-static int __pred_find_peer_by_id(const tsk_list_item_t *item, const void *id) {
- if (item && item->data) {
- return (int)(((const struct tnet_turn_peer_s *)item->data)->id - *((const tnet_turn_peer_id_t*)id));
- }
- return -1;
+static int __pred_find_peer_by_id(const tsk_list_item_t *item, const void *id)
+{
+ if (item && item->data) {
+ return (int)(((const struct tnet_turn_peer_s *)item->data)->id - *((const tnet_turn_peer_id_t*)id));
+ }
+ return -1;
}
-static int __pred_find_peer_by_fd(const tsk_list_item_t *item, const void *fd) {
- if (item && item->data) {
- return (int)(((const struct tnet_turn_peer_s *)item->data)->conn_fd - *((const tnet_fd_t*)fd));
- }
- return -1;
+static int __pred_find_peer_by_fd(const tsk_list_item_t *item, const void *fd)
+{
+ if (item && item->data) {
+ return (int)(((const struct tnet_turn_peer_s *)item->data)->conn_fd - *((const tnet_fd_t*)fd));
+ }
+ return -1;
}
-static int __pred_find_peer_by_channum(const tsk_list_item_t *item, const void *pu_chan_num) {
- if (item && item->data) {
- return (int)(((const struct tnet_turn_peer_s *)item->data)->u_chan_num - *((const uint16_t*)pu_chan_num));
- }
- return -1;
+static int __pred_find_peer_by_channum(const tsk_list_item_t *item, const void *pu_chan_num)
+{
+ if (item && item->data) {
+ return (int)(((const struct tnet_turn_peer_s *)item->data)->u_chan_num - *((const uint16_t*)pu_chan_num));
+ }
+ return -1;
}
-static int __pred_find_peer_by_timer_rtt_createperm(const tsk_list_item_t *item, const void *id) {
- if (item && item->data) {
- return (int)(((const struct tnet_turn_peer_s *)item->data)->timer.rtt.createperm.id - *((const tsk_timer_id_t*)id));
- }
- return -1;
+static int __pred_find_peer_by_timer_rtt_createperm(const tsk_list_item_t *item, const void *id)
+{
+ if (item && item->data) {
+ return (int)(((const struct tnet_turn_peer_s *)item->data)->timer.rtt.createperm.id - *((const tsk_timer_id_t*)id));
+ }
+ return -1;
}
-static int __pred_find_peer_by_timer_fresh_createperm(const tsk_list_item_t *item, const void *id) {
- if (item && item->data) {
- return (int)(((const struct tnet_turn_peer_s *)item->data)->timer.fresh.createperm.id - *((const tsk_timer_id_t*)id));
- }
- return -1;
+static int __pred_find_peer_by_timer_fresh_createperm(const tsk_list_item_t *item, const void *id)
+{
+ if (item && item->data) {
+ return (int)(((const struct tnet_turn_peer_s *)item->data)->timer.fresh.createperm.id - *((const tsk_timer_id_t*)id));
+ }
+ return -1;
}
-static int __pred_find_peer_by_transacid_createperm(const tsk_list_item_t *item, const void *pc_transacid) {
- if (item && item->data) {
- return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_createperm
- ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_createperm->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
- : +1;
- }
- return -1;
+static int __pred_find_peer_by_transacid_createperm(const tsk_list_item_t *item, const void *pc_transacid)
+{
+ if (item && item->data) {
+ return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_createperm
+ ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_createperm->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
+ : +1;
+ }
+ return -1;
}
-static int __pred_find_peer_by_timer_rtt_chanbind(const tsk_list_item_t *item, const void *id) {
- if (item && item->data) {
- return (int)(((const struct tnet_turn_peer_s *)item->data)->timer.rtt.chanbind.id - *((const tsk_timer_id_t*)id));
- }
- return -1;
+static int __pred_find_peer_by_timer_rtt_chanbind(const tsk_list_item_t *item, const void *id)
+{
+ if (item && item->data) {
+ return (int)(((const struct tnet_turn_peer_s *)item->data)->timer.rtt.chanbind.id - *((const tsk_timer_id_t*)id));
+ }
+ return -1;
}
-static int __pred_find_peer_by_timer_fresh_chanbind(const tsk_list_item_t *item, const void *id) {
- if (item && item->data) {
- return (int)(((const struct tnet_turn_peer_s *)item->data)->timer.fresh.chanbind.id - *((const tsk_timer_id_t*)id));
- }
- return -1;
+static int __pred_find_peer_by_timer_fresh_chanbind(const tsk_list_item_t *item, const void *id)
+{
+ if (item && item->data) {
+ return (int)(((const struct tnet_turn_peer_s *)item->data)->timer.fresh.chanbind.id - *((const tsk_timer_id_t*)id));
+ }
+ return -1;
}
-static int __pred_find_peer_by_transacid_chanbind(const tsk_list_item_t *item, const void *pc_transacid) {
- if (item && item->data) {
- return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_chanbind
- ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_chanbind->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
- : +1;
- }
- return -1;
+static int __pred_find_peer_by_transacid_chanbind(const tsk_list_item_t *item, const void *pc_transacid)
+{
+ if (item && item->data) {
+ return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_chanbind
+ ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_chanbind->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
+ : +1;
+ }
+ return -1;
}
-static int __pred_find_peer_by_transacid_connect(const tsk_list_item_t *item, const void *pc_transacid) {
- if (item && item->data) {
- return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_connect
- ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_connect->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
- : +1;
- }
- return -1;
+static int __pred_find_peer_by_transacid_connect(const tsk_list_item_t *item, const void *pc_transacid)
+{
+ if (item && item->data) {
+ return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_connect
+ ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_connect->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
+ : +1;
+ }
+ return -1;
}
-static int __pred_find_peer_by_transacid_connectionbind(const tsk_list_item_t *item, const void *pc_transacid) {
- if (item && item->data) {
- return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_connbind
- ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_connbind->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
- : +1;
- }
- return -1;
+static int __pred_find_peer_by_transacid_connectionbind(const tsk_list_item_t *item, const void *pc_transacid)
+{
+ if (item && item->data) {
+ return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_connbind
+ ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_connbind->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
+ : +1;
+ }
+ return -1;
}
-static int __pred_find_peer_by_transacid_sendind(const tsk_list_item_t *item, const void *pc_transacid) {
- if (item && item->data) {
- return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_sendind
- ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_sendind->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
- : +1;
- }
- return -1;
+static int __pred_find_peer_by_transacid_sendind(const tsk_list_item_t *item, const void *pc_transacid)
+{
+ if (item && item->data) {
+ return ((const struct tnet_turn_peer_s *)item->data)->p_pkt_sendind
+ ? tnet_stun_utils_transac_id_cmp(((const struct tnet_turn_peer_s *)item->data)->p_pkt_sendind->transac_id, *((const tnet_stun_transac_id_t*)pc_transacid))
+ : +1;
+ }
+ return -1;
}
#define _tnet_turn_session_raise_event0(_p_self, _e_type, _u_peer_id) \
@@ -321,117 +331,117 @@ static int __pred_find_peer_by_transacid_sendind(const tsk_list_item_t *item, co
int tnet_turn_session_create(struct tnet_socket_s* p_lcl_sock, enum tnet_turn_transport_e e_req_transport, const char* pc_srv_host, uint16_t u_srv_port, struct tnet_turn_session_s** pp_self)
{
- int ret;
- extern const tsk_object_def_t *tnet_turn_session_def_t;
- tnet_turn_session_t* p_self;
- if (!p_lcl_sock || !TNET_SOCKET_IS_VALID(p_lcl_sock) || !pc_srv_host || !u_srv_port || !pp_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if (!(p_self = tsk_object_new(tnet_turn_session_def_t))) {
- TSK_DEBUG_ERROR("Failed to create 'tnet_turn_session_def_t' object");
- return -2;
- }
- if (!(p_self->p_list_peers = tsk_list_create())) {
- TSK_DEBUG_ERROR("Failed to create list");
- ret = -3;
- goto bail;
- }
- if (TNET_SOCKET_TYPE_IS_STREAM(p_lcl_sock->type) && !(p_self->p_stream_buff_in = tsk_buffer_create_null())) {
- TSK_DEBUG_ERROR("Failed to stream buffer");
- ret = -4;
- goto bail;
- }
- if ((ret = tnet_sockaddr_init(pc_srv_host, u_srv_port, p_lcl_sock->type, &p_self->srv_addr))) {
- TSK_DEBUG_ERROR("Invalid TURN SRV address [%s:%u]", pc_srv_host, u_srv_port);
- goto bail;
- }
- tsk_strupdate(&p_self->p_srv_host, pc_srv_host);
- p_self->u_srv_port = u_srv_port;
- p_self->p_lcl_sock = tsk_object_ref(p_lcl_sock);
- p_self->e_req_transport = e_req_transport;
- p_self->cb.e.pc_session = p_self;
- *pp_self = p_self;
+ int ret;
+ extern const tsk_object_def_t *tnet_turn_session_def_t;
+ tnet_turn_session_t* p_self;
+ if (!p_lcl_sock || !TNET_SOCKET_IS_VALID(p_lcl_sock) || !pc_srv_host || !u_srv_port || !pp_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if (!(p_self = tsk_object_new(tnet_turn_session_def_t))) {
+ TSK_DEBUG_ERROR("Failed to create 'tnet_turn_session_def_t' object");
+ return -2;
+ }
+ if (!(p_self->p_list_peers = tsk_list_create())) {
+ TSK_DEBUG_ERROR("Failed to create list");
+ ret = -3;
+ goto bail;
+ }
+ if (TNET_SOCKET_TYPE_IS_STREAM(p_lcl_sock->type) && !(p_self->p_stream_buff_in = tsk_buffer_create_null())) {
+ TSK_DEBUG_ERROR("Failed to stream buffer");
+ ret = -4;
+ goto bail;
+ }
+ if ((ret = tnet_sockaddr_init(pc_srv_host, u_srv_port, p_lcl_sock->type, &p_self->srv_addr))) {
+ TSK_DEBUG_ERROR("Invalid TURN SRV address [%s:%u]", pc_srv_host, u_srv_port);
+ goto bail;
+ }
+ tsk_strupdate(&p_self->p_srv_host, pc_srv_host);
+ p_self->u_srv_port = u_srv_port;
+ p_self->p_lcl_sock = tsk_object_ref(p_lcl_sock);
+ p_self->e_req_transport = e_req_transport;
+ p_self->cb.e.pc_session = p_self;
+ *pp_self = p_self;
bail:
- if (ret) {
- TSK_OBJECT_SAFE_FREE(p_self);
- }
- return ret;
+ if (ret) {
+ TSK_OBJECT_SAFE_FREE(p_self);
+ }
+ return ret;
}
int tnet_turn_session_create_2(const char* pc_lcl_ip, uint16_t u_lcl_port, enum tnet_socket_type_e e_lcl_type, enum tnet_turn_transport_e e_req_transport, const char* pc_srv_host, uint16_t u_srv_port, struct tnet_turn_session_s** pp_self)
{
- tnet_socket_t* p_lcl_sock;
- int ret;
- if (!pc_srv_host || !u_srv_port || !pp_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if(!(p_lcl_sock = tnet_socket_create(pc_lcl_ip, u_lcl_port, e_lcl_type))) {
- TSK_DEBUG_ERROR("Failed to create socket(%s:%u$%d)", pc_lcl_ip, u_lcl_port, e_lcl_type);
- return -2;
- }
- ret = tnet_turn_session_create(p_lcl_sock, e_req_transport, pc_srv_host, u_srv_port, pp_self);
- TSK_OBJECT_SAFE_FREE(p_lcl_sock);
- return ret;
+ tnet_socket_t* p_lcl_sock;
+ int ret;
+ if (!pc_srv_host || !u_srv_port || !pp_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if(!(p_lcl_sock = tnet_socket_create(pc_lcl_ip, u_lcl_port, e_lcl_type))) {
+ TSK_DEBUG_ERROR("Failed to create socket(%s:%u$%d)", pc_lcl_ip, u_lcl_port, e_lcl_type);
+ return -2;
+ }
+ ret = tnet_turn_session_create(p_lcl_sock, e_req_transport, pc_srv_host, u_srv_port, pp_self);
+ TSK_OBJECT_SAFE_FREE(p_lcl_sock);
+ return ret;
}
int tnet_turn_session_create_4(struct tnet_socket_s* p_lcl_sock, enum tnet_turn_transport_e e_req_transport, const char* pc_srv_host, uint16_t u_srv_port, enum tnet_socket_type_e e_srv_type, struct tnet_turn_session_s** pp_self)
{
- struct tnet_socket_s* _p_lcl_sock;
- int ret;
+ struct tnet_socket_s* _p_lcl_sock;
+ int ret;
- if (TNET_SOCKET_TYPE_IS_STREAM(e_srv_type)) {
- // For stream the socket will be connected to the server and this is why we need to create a new socket
- if (!(_p_lcl_sock = tnet_socket_create(p_lcl_sock->ip, TNET_SOCKET_PORT_ANY/*p_lcl_sock->port*/, e_srv_type))) {
- return -2;
- }
- }
- else {
- // For UDP, use the socket socket
- _p_lcl_sock = tsk_object_ref(p_lcl_sock);
- }
- ret = tnet_turn_session_create(_p_lcl_sock, e_req_transport, pc_srv_host, u_srv_port, pp_self);
- TSK_OBJECT_SAFE_FREE(_p_lcl_sock);
- return ret;
+ if (TNET_SOCKET_TYPE_IS_STREAM(e_srv_type)) {
+ // For stream the socket will be connected to the server and this is why we need to create a new socket
+ if (!(_p_lcl_sock = tnet_socket_create(p_lcl_sock->ip, TNET_SOCKET_PORT_ANY/*p_lcl_sock->port*/, e_srv_type))) {
+ return -2;
+ }
+ }
+ else {
+ // For UDP, use the socket socket
+ _p_lcl_sock = tsk_object_ref(p_lcl_sock);
+ }
+ ret = tnet_turn_session_create(_p_lcl_sock, e_req_transport, pc_srv_host, u_srv_port, pp_self);
+ TSK_OBJECT_SAFE_FREE(_p_lcl_sock);
+ return ret;
}
int tnet_turn_session_set_cred(tnet_turn_session_t* p_self, const char* pc_usr_name, const char* pc_pwd)
{
- if (!p_self || !pc_usr_name || !pc_pwd) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_strupdate(&p_self->cred.p_usr_name, pc_usr_name);
- tsk_strupdate(&p_self->cred.p_pwd, pc_pwd);
+ if (!p_self || !pc_usr_name || !pc_pwd) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_strupdate(&p_self->cred.p_usr_name, pc_usr_name);
+ tsk_strupdate(&p_self->cred.p_pwd, pc_pwd);
- return 0;
+ return 0;
}
int tnet_turn_session_set_callback(struct tnet_turn_session_s* p_self, tnet_turn_session_callback_f f_fun, const void* pc_usr_data)
{
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- p_self->cb.f_fun = f_fun;
- p_self->cb.e.pc_usr_data = pc_usr_data;
- return 0;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ p_self->cb.f_fun = f_fun;
+ p_self->cb.e.pc_usr_data = pc_usr_data;
+ return 0;
}
int tnet_turn_session_set_ssl_certs(struct tnet_turn_session_s* p_self, const char* path_priv, const char* path_pub, const char* path_ca, tsk_bool_t verify)
{
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(p_self);
- tsk_strupdate(&p_self->ssl.path_priv, path_priv);
- tsk_strupdate(&p_self->ssl.path_pub, path_pub);
- tsk_strupdate(&p_self->ssl.path_ca, path_ca);
- p_self->ssl.verify = verify;
- tsk_safeobj_unlock(p_self);
- return 0;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(p_self);
+ tsk_strupdate(&p_self->ssl.path_priv, path_priv);
+ tsk_strupdate(&p_self->ssl.path_pub, path_pub);
+ tsk_strupdate(&p_self->ssl.path_ca, path_ca);
+ p_self->ssl.verify = verify;
+ tsk_safeobj_unlock(p_self);
+ return 0;
}
int tnet_turn_session_set_proxy_auto_detect(struct tnet_turn_session_s* p_self, tsk_bool_t auto_detect)
@@ -461,99 +471,99 @@ int tnet_turn_session_set_proxy_info(struct tnet_turn_session_s* p_self, struct
int tnet_turn_session_prepare(tnet_turn_session_t* p_self)
{
- int ret = 0;
+ int ret = 0;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (p_self->b_prepared) {
- goto bail;
- }
+ if (p_self->b_prepared) {
+ goto bail;
+ }
- p_self->e_alloc_state = tnet_stun_state_none;
- p_self->e_refresh_state = tnet_stun_state_none;
+ p_self->e_alloc_state = tnet_stun_state_none;
+ p_self->e_refresh_state = tnet_stun_state_none;
- p_self->timer.rtt.alloc.id = TSK_INVALID_TIMER_ID;
- p_self->timer.rtt.refresh.id = TSK_INVALID_TIMER_ID;
+ p_self->timer.rtt.alloc.id = TSK_INVALID_TIMER_ID;
+ p_self->timer.rtt.refresh.id = TSK_INVALID_TIMER_ID;
- p_self->timer.u_timer_id_refresh = TSK_INVALID_TIMER_ID;
- p_self->u_lifetime_alloc_in_sec = kTurnAllocationTimeOutInSec;
+ p_self->timer.u_timer_id_refresh = TSK_INVALID_TIMER_ID;
+ p_self->u_lifetime_alloc_in_sec = kTurnAllocationTimeOutInSec;
- TSK_OBJECT_SAFE_FREE(p_self->p_pkt_alloc);
- TSK_OBJECT_SAFE_FREE(p_self->p_pkt_refresh);
+ TSK_OBJECT_SAFE_FREE(p_self->p_pkt_alloc);
+ TSK_OBJECT_SAFE_FREE(p_self->p_pkt_refresh);
- // create timer manager
- if (!p_self->timer.p_mgr && !(p_self->timer.p_mgr = tsk_timer_manager_create())) {
- TSK_DEBUG_ERROR("Failed to create timer manager");
+ // create timer manager
+ if (!p_self->timer.p_mgr && !(p_self->timer.p_mgr = tsk_timer_manager_create())) {
+ TSK_DEBUG_ERROR("Failed to create timer manager");
ret = -4;
- goto bail;
- }
+ goto bail;
+ }
- // create transport
+ // create transport
if (!p_self->p_transport) {
- if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
- // Use the DGram socket as master
- p_self->p_transport = tnet_transport_create_2(p_self->p_lcl_sock, kTurnTransportFriendlyName);
- }
- else {
- // Use the Stream socket later and connect it
- p_self->p_transport = tnet_transport_create(p_self->p_lcl_sock->ip, TNET_SOCKET_PORT_ANY, p_self->p_lcl_sock->type, kTurnTransportFriendlyName);
- }
- if (!p_self->p_transport) {
- TSK_DEBUG_ERROR("Failed to create %s Transport", kTurnTransportFriendlyName);
- ret = -5;
- goto bail;
- }
+ if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
+ // Use the DGram socket as master
+ p_self->p_transport = tnet_transport_create_2(p_self->p_lcl_sock, kTurnTransportFriendlyName);
+ }
+ else {
+ // Use the Stream socket later and connect it
+ p_self->p_transport = tnet_transport_create(p_self->p_lcl_sock->ip, TNET_SOCKET_PORT_ANY, p_self->p_lcl_sock->type, kTurnTransportFriendlyName);
+ }
+ if (!p_self->p_transport) {
+ TSK_DEBUG_ERROR("Failed to create %s Transport", kTurnTransportFriendlyName);
+ ret = -5;
+ goto bail;
+ }
}
// set transport callback
- if ((ret = tnet_transport_set_callback(p_self->p_transport, TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type) ? _tnet_turn_session_transport_layer_dgram_cb : _tnet_turn_session_transport_layer_stream_cb, p_self))) {
+ if ((ret = tnet_transport_set_callback(p_self->p_transport, TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type) ? _tnet_turn_session_transport_layer_dgram_cb : _tnet_turn_session_transport_layer_stream_cb, p_self))) {
goto bail;
- }
+ }
- p_self->b_prepared = tsk_true;
+ p_self->b_prepared = tsk_true;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
int tnet_turn_session_start(tnet_turn_session_t* p_self)
{
- int ret = 0;
+ int ret = 0;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (p_self->b_started) {
- goto bail;
- }
- if (!p_self->b_prepared) {
- TSK_DEBUG_ERROR("TURN session not prepared yet");
- ret = -2;
- goto bail;
- }
+ if (p_self->b_started) {
+ goto bail;
+ }
+ if (!p_self->b_prepared) {
+ TSK_DEBUG_ERROR("TURN session not prepared yet");
+ ret = -2;
+ goto bail;
+ }
- // start timer manager
- if ((ret = tsk_timer_manager_start(p_self->timer.p_mgr))) {
- TSK_DEBUG_ERROR("Failed to start TURN timer manager");
- goto bail;
- }
+ // start timer manager
+ if ((ret = tsk_timer_manager_start(p_self->timer.p_mgr))) {
+ TSK_DEBUG_ERROR("Failed to start TURN timer manager");
+ goto bail;
+ }
+
+ // set SSL certificates
+ if (TNET_SOCKET_TYPE_IS_TLS(p_self->p_lcl_sock->type) || TNET_SOCKET_TYPE_IS_WSS(p_self->p_lcl_sock->type)) {
+ if ((ret = tnet_transport_tls_set_certs(p_self->p_transport, p_self->ssl.path_ca, p_self->ssl.path_pub, p_self->ssl.path_priv, p_self->ssl.verify))) {
+ TSK_DEBUG_ERROR("Failed to set SSL certificates: '%s', '%s', '%s'", p_self->ssl.path_ca, p_self->ssl.path_pub, p_self->ssl.path_priv);
+ goto bail;
+ }
+ }
- // set SSL certificates
- if (TNET_SOCKET_TYPE_IS_TLS(p_self->p_lcl_sock->type) || TNET_SOCKET_TYPE_IS_WSS(p_self->p_lcl_sock->type)) {
- if ((ret = tnet_transport_tls_set_certs(p_self->p_transport, p_self->ssl.path_ca, p_self->ssl.path_pub, p_self->ssl.path_priv, p_self->ssl.verify))) {
- TSK_DEBUG_ERROR("Failed to set SSL certificates: '%s', '%s', '%s'", p_self->ssl.path_ca, p_self->ssl.path_pub, p_self->ssl.path_priv);
- goto bail;
- }
- }
-
// Proxy info
if ((ret = tnet_transport_set_proxy_auto_detect(p_self->p_transport, p_self->proxy.auto_detect))) {
TSK_DEBUG_ERROR("Failed to set proxy autodetect option");
@@ -566,218 +576,218 @@ int tnet_turn_session_start(tnet_turn_session_t* p_self)
}
}
- // start network transport
- if ((ret = tnet_transport_start(p_self->p_transport))) {
- TSK_DEBUG_ERROR("Failed to start TURN transport");
- goto bail;
- }
-
- // Connect to the server
- if (TNET_SOCKET_TYPE_IS_STREAM(p_self->p_lcl_sock->type)) {
- tnet_fd_t fd;
- p_self->b_stream_connected = tsk_false;
- p_self->b_stream_error = tsk_false;
- fd = tnet_transport_connectto_3(p_self->p_transport, p_self->p_lcl_sock, p_self->p_srv_host, p_self->u_srv_port, p_self->p_lcl_sock->type);
- if (fd != p_self->p_lcl_sock->fd) {
- TSK_DEBUG_ERROR("Failed to connect to TURN server(%s:%d)", p_self->p_srv_host, p_self->u_srv_port);
- ret = -3;
- goto bail;
- }
- TSK_DEBUG_INFO("TURN server connection fd = %d", p_self->p_lcl_sock->fd);
- }
+ // start network transport
+ if ((ret = tnet_transport_start(p_self->p_transport))) {
+ TSK_DEBUG_ERROR("Failed to start TURN transport");
+ goto bail;
+ }
+
+ // Connect to the server
+ if (TNET_SOCKET_TYPE_IS_STREAM(p_self->p_lcl_sock->type)) {
+ tnet_fd_t fd;
+ p_self->b_stream_connected = tsk_false;
+ p_self->b_stream_error = tsk_false;
+ fd = tnet_transport_connectto_3(p_self->p_transport, p_self->p_lcl_sock, p_self->p_srv_host, p_self->u_srv_port, p_self->p_lcl_sock->type);
+ if (fd != p_self->p_lcl_sock->fd) {
+ TSK_DEBUG_ERROR("Failed to connect to TURN server(%s:%d)", p_self->p_srv_host, p_self->u_srv_port);
+ ret = -3;
+ goto bail;
+ }
+ TSK_DEBUG_INFO("TURN server connection fd = %d", p_self->p_lcl_sock->fd);
+ }
- p_self->b_started = tsk_true;
+ p_self->b_started = tsk_true;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
int tnet_turn_session_allocate(tnet_turn_session_t* p_self)
{
- int ret = 0;
+ int ret = 0;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
- // create Allocate Request
- p_self->e_alloc_state = tnet_stun_state_none;
- p_self->timer.rtt.alloc.id = TSK_INVALID_TIMER_ID;
- TSK_OBJECT_SAFE_FREE(p_self->p_pkt_alloc);
- if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_allocate_request, &p_self->p_pkt_alloc))) {
- TSK_DEBUG_ERROR("Failed to create TURN Allocate request");
- goto bail;
- }
- // add attributes
- p_self->p_pkt_alloc->opt.dontfrag = 0;
- ret = tnet_stun_pkt_attrs_add(p_self->p_pkt_alloc,
- TNET_STUN_PKT_ATTR_ADD_LIFETIME(p_self->u_lifetime_alloc_in_sec),
- TNET_STUN_PKT_ATTR_ADD_REQUESTED_TRANSPORT(p_self->e_req_transport),
- TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware), // recommended for Alloc and Refresh
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
-
- if ((ret = _tnet_turn_session_send_pkt(p_self, p_self->p_pkt_alloc))) {
- goto bail;
- }
- if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
- p_self->timer.rtt.alloc.u_timeout = kStunUdpRetransmitTimoutMinInMs;
- TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, p_self->timer.rtt.alloc.id, p_self->timer.rtt.alloc.u_timeout);
- }
- p_self->e_alloc_state = tnet_stun_state_trying;
+ // create Allocate Request
+ p_self->e_alloc_state = tnet_stun_state_none;
+ p_self->timer.rtt.alloc.id = TSK_INVALID_TIMER_ID;
+ TSK_OBJECT_SAFE_FREE(p_self->p_pkt_alloc);
+ if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_allocate_request, &p_self->p_pkt_alloc))) {
+ TSK_DEBUG_ERROR("Failed to create TURN Allocate request");
+ goto bail;
+ }
+ // add attributes
+ p_self->p_pkt_alloc->opt.dontfrag = 0;
+ ret = tnet_stun_pkt_attrs_add(p_self->p_pkt_alloc,
+ TNET_STUN_PKT_ATTR_ADD_LIFETIME(p_self->u_lifetime_alloc_in_sec),
+ TNET_STUN_PKT_ATTR_ADD_REQUESTED_TRANSPORT(p_self->e_req_transport),
+ TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware), // recommended for Alloc and Refresh
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+
+ if ((ret = _tnet_turn_session_send_pkt(p_self, p_self->p_pkt_alloc))) {
+ goto bail;
+ }
+ if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
+ p_self->timer.rtt.alloc.u_timeout = kStunUdpRetransmitTimoutMinInMs;
+ TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, p_self->timer.rtt.alloc.id, p_self->timer.rtt.alloc.u_timeout);
+ }
+ p_self->e_alloc_state = tnet_stun_state_trying;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
int tnet_turn_session_get_relayed_addr(const struct tnet_turn_session_s* p_self, char** pp_ip, uint16_t *pu_port, tsk_bool_t *pb_ipv6)
{
- int ret = 0;
+ int ret = 0;
- if (!p_self || !pp_ip || !pu_port || !pb_ipv6) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self || !pp_ip || !pu_port || !pb_ipv6) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -4;
- goto bail;
- }
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -4;
+ goto bail;
+ }
- tsk_strupdate(pp_ip, p_self->p_rel_ip);
- *pu_port = p_self->u_rel_port;
- *pb_ipv6 = p_self->b_rel_ipv6;
+ tsk_strupdate(pp_ip, p_self->p_rel_ip);
+ *pu_port = p_self->u_rel_port;
+ *pb_ipv6 = p_self->b_rel_ipv6;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
int tnet_turn_session_get_srflx_addr(const tnet_turn_session_t* p_self, char** pp_ip, uint16_t *pu_port, tsk_bool_t *pb_ipv6)
{
- int ret = 0;
+ int ret = 0;
- if (!p_self || !pp_ip || !pu_port || !pb_ipv6) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self || !pp_ip || !pu_port || !pb_ipv6) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -4;
- goto bail;
- }
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -4;
+ goto bail;
+ }
- tsk_strupdate(pp_ip, p_self->p_srflx_ip);
- *pu_port = p_self->u_srflx_port;
- *pb_ipv6 = p_self->b_srflx_ipv6;
+ tsk_strupdate(pp_ip, p_self->p_srflx_ip);
+ *pu_port = p_self->u_srflx_port;
+ *pb_ipv6 = p_self->b_srflx_ipv6;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
int tnet_turn_session_get_state_alloc(const struct tnet_turn_session_s* pc_self, enum tnet_stun_state_e *pe_state)
{
- if (!pc_self || !pe_state) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *pe_state = pc_self->e_alloc_state;
- return 0;
+ if (!pc_self || !pe_state) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *pe_state = pc_self->e_alloc_state;
+ return 0;
}
int tnet_turn_session_get_socket_local(struct tnet_turn_session_s* p_self, struct tnet_socket_s** pp_lcl_sock)
{
- if (!p_self || !pp_lcl_sock) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(p_self);
- *pp_lcl_sock = (struct tnet_socket_s*)tsk_object_ref(p_self->p_lcl_sock);
- tsk_safeobj_unlock(p_self);
- return 0;
+ if (!p_self || !pp_lcl_sock) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(p_self);
+ *pp_lcl_sock = (struct tnet_socket_s*)tsk_object_ref(p_self->p_lcl_sock);
+ tsk_safeobj_unlock(p_self);
+ return 0;
}
int tnet_turn_session_get_state_createperm(const struct tnet_turn_session_s* pc_self, tnet_turn_peer_id_t u_peer_id, enum tnet_stun_state_e *pe_state)
{
- const tnet_turn_peer_t *pc_peer;
- if (!pc_self || !pe_state) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(pc_self);
- if ((pc_peer = tsk_list_find_object_by_pred(pc_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
- *pe_state = pc_peer->e_createperm_state;
- }
- else {
- *pe_state = tnet_stun_state_none;
- if (u_peer_id != kTurnPeerIdInvalid) {
- TSK_DEBUG_WARN("TURN peer with id =%ld doesn't exist", u_peer_id);
- }
- }
- tsk_safeobj_unlock(pc_self);
- return 0;
+ const tnet_turn_peer_t *pc_peer;
+ if (!pc_self || !pe_state) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(pc_self);
+ if ((pc_peer = tsk_list_find_object_by_pred(pc_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
+ *pe_state = pc_peer->e_createperm_state;
+ }
+ else {
+ *pe_state = tnet_stun_state_none;
+ if (u_peer_id != kTurnPeerIdInvalid) {
+ TSK_DEBUG_WARN("TURN peer with id =%ld doesn't exist", u_peer_id);
+ }
+ }
+ tsk_safeobj_unlock(pc_self);
+ return 0;
}
int tnet_turn_session_get_state_connbind(const struct tnet_turn_session_s* pc_self, tnet_turn_peer_id_t u_peer_id, enum tnet_stun_state_e *pe_state)
{
- const tnet_turn_peer_t *pc_peer;
- if (!pc_self || !pe_state) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(pc_self);
- if ((pc_peer = tsk_list_find_object_by_pred(pc_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
- *pe_state = pc_peer->e_connbind_state;
- }
- else {
- *pe_state = tnet_stun_state_none;
- if (u_peer_id != kTurnPeerIdInvalid) {
- TSK_DEBUG_WARN("TURN peer with id =%ld doesn't exist", u_peer_id);
- }
- }
- tsk_safeobj_unlock(pc_self);
- return 0;
+ const tnet_turn_peer_t *pc_peer;
+ if (!pc_self || !pe_state) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(pc_self);
+ if ((pc_peer = tsk_list_find_object_by_pred(pc_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
+ *pe_state = pc_peer->e_connbind_state;
+ }
+ else {
+ *pe_state = tnet_stun_state_none;
+ if (u_peer_id != kTurnPeerIdInvalid) {
+ TSK_DEBUG_WARN("TURN peer with id =%ld doesn't exist", u_peer_id);
+ }
+ }
+ tsk_safeobj_unlock(pc_self);
+ return 0;
}
int tnet_turn_session_get_req_transport(const struct tnet_turn_session_s* pc_self, enum tnet_turn_transport_e *pe_transport)
{
- if (!pc_self || !pe_transport) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(pc_self);
- *pe_transport = pc_self->e_req_transport;
- tsk_safeobj_unlock(pc_self);
- return 0;
+ if (!pc_self || !pe_transport) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(pc_self);
+ *pe_transport = pc_self->e_req_transport;
+ tsk_safeobj_unlock(pc_self);
+ return 0;
}
int tnet_turn_session_get_bytes_count(const struct tnet_turn_session_s* pc_self, uint64_t* bytes_in, uint64_t* bytes_out)
@@ -791,459 +801,459 @@ int tnet_turn_session_get_bytes_count(const struct tnet_turn_session_s* pc_self,
int tnet_turn_session_createpermission(struct tnet_turn_session_s* p_self, const char* pc_peer_addr, uint16_t u_peer_port, tnet_turn_peer_id_t* pu_id)
{
- int ret = 0;
- tnet_turn_peer_t *p_peer = tsk_null;
+ int ret = 0;
+ tnet_turn_peer_t *p_peer = tsk_null;
- if (!p_self || !pc_peer_addr || !u_peer_port || !pu_id) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- tsk_safeobj_lock(p_self);
+ if (!p_self || !pc_peer_addr || !u_peer_port || !pu_id) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -4;
- goto bail;
- }
- if ((ret = _tnet_turn_peer_create(pc_peer_addr, u_peer_port, TNET_SOCKET_TYPE_IS_IPV6(p_self->p_lcl_sock->type), &p_peer))) {
- goto bail;
- }
- if (TNET_SOCKET_TYPE_IS_STREAM(p_self->p_lcl_sock->type)) {
- if (!p_peer->p_stream_buff_in && !(p_peer->p_stream_buff_in = tsk_buffer_create_null())) {
- TSK_DEBUG_ERROR("Failed to create stream buffer for peer with id=%ld", p_peer->id);
- ret = -5;
- goto bail;
- }
- }
- if ((ret = _tnet_turn_session_send_permission(p_self, p_peer))) {
- goto bail;
- }
- *pu_id = p_peer->id;
- tsk_list_push_back_data(p_self->p_list_peers, (void**)&p_peer);
+ tsk_safeobj_lock(p_self);
+
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -4;
+ goto bail;
+ }
+ if ((ret = _tnet_turn_peer_create(pc_peer_addr, u_peer_port, TNET_SOCKET_TYPE_IS_IPV6(p_self->p_lcl_sock->type), &p_peer))) {
+ goto bail;
+ }
+ if (TNET_SOCKET_TYPE_IS_STREAM(p_self->p_lcl_sock->type)) {
+ if (!p_peer->p_stream_buff_in && !(p_peer->p_stream_buff_in = tsk_buffer_create_null())) {
+ TSK_DEBUG_ERROR("Failed to create stream buffer for peer with id=%ld", p_peer->id);
+ ret = -5;
+ goto bail;
+ }
+ }
+ if ((ret = _tnet_turn_session_send_permission(p_self, p_peer))) {
+ goto bail;
+ }
+ *pu_id = p_peer->id;
+ tsk_list_push_back_data(p_self->p_list_peers, (void**)&p_peer);
bail:
- TSK_OBJECT_SAFE_FREE(p_peer);
- tsk_safeobj_unlock(p_self);
- return ret;
+ TSK_OBJECT_SAFE_FREE(p_peer);
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
int tnet_turn_session_deletepermission(struct tnet_turn_session_s* p_self, tnet_turn_peer_id_t u_id)
{
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(p_self);
- tsk_list_remove_item_by_pred(p_self->p_list_peers, __pred_find_peer_by_id, &u_id);
- tsk_safeobj_unlock(p_self);
- return 0;
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(p_self);
+ tsk_list_remove_item_by_pred(p_self->p_list_peers, __pred_find_peer_by_id, &u_id);
+ tsk_safeobj_unlock(p_self);
+ return 0;
}
int tnet_turn_session_chanbind(tnet_turn_session_t* p_self, tnet_turn_peer_id_t u_peer_id)
{
- int ret = 0;
- tnet_turn_peer_t *pc_peer;
+ int ret = 0;
+ tnet_turn_peer_t *pc_peer;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -4;
- goto bail;
- }
- if (!(pc_peer = (tnet_turn_peer_t *)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
- TSK_DEBUG_ERROR("Cannot find TURN peer with id = %ld", u_peer_id);
- ret = -5;
- goto bail;
- }
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -4;
+ goto bail;
+ }
+ if (!(pc_peer = (tnet_turn_peer_t *)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
+ TSK_DEBUG_ERROR("Cannot find TURN peer with id = %ld", u_peer_id);
+ ret = -5;
+ goto bail;
+ }
- // ChannelBind must not be used for streams (e.g. TCP, TLS....)
- if (p_self->e_req_transport != tnet_turn_transport_udp) {
- TSK_DEBUG_ERROR("TURN ChannelBind not supported for stream");
- ret = -6;
- goto bail;
- }
+ // ChannelBind must not be used for streams (e.g. TCP, TLS....)
+ if (p_self->e_req_transport != tnet_turn_transport_udp) {
+ TSK_DEBUG_ERROR("TURN ChannelBind not supported for stream");
+ ret = -6;
+ goto bail;
+ }
- // create ChannelBind Request if doesn't exist (ChannelBind refresh *must* have same id)
- pc_peer->e_chanbind_state = tnet_stun_state_none;
- pc_peer->timer.rtt.chanbind.id = TSK_INVALID_TIMER_ID;
- if (!pc_peer->p_pkt_chanbind) {
- pc_peer->u_chan_num = _tnet_turn_session_get_unique_chan_num();
- if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_channelbind_request, &pc_peer->p_pkt_chanbind))) {
- TSK_DEBUG_ERROR("Failed to create TURN ChannelBind request");
- goto bail;
- }
- // add authentication info
- tnet_stun_pkt_auth_copy(pc_peer->p_pkt_chanbind, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
- // add attributes
- pc_peer->p_pkt_chanbind->opt.dontfrag = 0;
- ret = tnet_stun_pkt_attrs_add(pc_peer->p_pkt_chanbind,
- /* Must not add LIFETIME and there is no way to delete permission */
- TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(pc_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, pc_peer->u_addr_port, &pc_peer->addr_ip),
- TNET_STUN_PKT_ATTR_ADD_CHANNEL_NUMBER(pc_peer->u_chan_num),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
-
- }
- else {
- if ((ret = tnet_stun_utils_transac_id_rand(&pc_peer->p_pkt_chanbind->transac_id))) {
- goto bail;
- }
- }
-
- if ((ret = _tnet_turn_session_send_pkt(p_self, pc_peer->p_pkt_chanbind))) {
- goto bail;
- }
- if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
- pc_peer->timer.rtt.chanbind.u_timeout = kStunUdpRetransmitTimoutMinInMs;
- TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, pc_peer->timer.rtt.chanbind.id, pc_peer->timer.rtt.chanbind.u_timeout);
- }
- pc_peer->e_chanbind_state = tnet_stun_state_trying;
+ // create ChannelBind Request if doesn't exist (ChannelBind refresh *must* have same id)
+ pc_peer->e_chanbind_state = tnet_stun_state_none;
+ pc_peer->timer.rtt.chanbind.id = TSK_INVALID_TIMER_ID;
+ if (!pc_peer->p_pkt_chanbind) {
+ pc_peer->u_chan_num = _tnet_turn_session_get_unique_chan_num();
+ if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_channelbind_request, &pc_peer->p_pkt_chanbind))) {
+ TSK_DEBUG_ERROR("Failed to create TURN ChannelBind request");
+ goto bail;
+ }
+ // add authentication info
+ tnet_stun_pkt_auth_copy(pc_peer->p_pkt_chanbind, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
+ // add attributes
+ pc_peer->p_pkt_chanbind->opt.dontfrag = 0;
+ ret = tnet_stun_pkt_attrs_add(pc_peer->p_pkt_chanbind,
+ /* Must not add LIFETIME and there is no way to delete permission */
+ TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(pc_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, pc_peer->u_addr_port, &pc_peer->addr_ip),
+ TNET_STUN_PKT_ATTR_ADD_CHANNEL_NUMBER(pc_peer->u_chan_num),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+
+ }
+ else {
+ if ((ret = tnet_stun_utils_transac_id_rand(&pc_peer->p_pkt_chanbind->transac_id))) {
+ goto bail;
+ }
+ }
+
+ if ((ret = _tnet_turn_session_send_pkt(p_self, pc_peer->p_pkt_chanbind))) {
+ goto bail;
+ }
+ if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
+ pc_peer->timer.rtt.chanbind.u_timeout = kStunUdpRetransmitTimoutMinInMs;
+ TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, pc_peer->timer.rtt.chanbind.id, pc_peer->timer.rtt.chanbind.u_timeout);
+ }
+ pc_peer->e_chanbind_state = tnet_stun_state_trying;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
// TCP-Connect rfc6062 - 4.3. Initiating a Connection
int tnet_turn_session_connect(struct tnet_turn_session_s* p_self, tnet_turn_peer_id_t u_peer_id)
{
- int ret = 0;
- tnet_turn_peer_t *pc_peer;
+ int ret = 0;
+ tnet_turn_peer_t *pc_peer;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -4;
- goto bail;
- }
- if (!(pc_peer = (tnet_turn_peer_t *)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
- TSK_DEBUG_ERROR("Cannot find TURN peer with id = %ld", u_peer_id);
- ret = -5;
- goto bail;
- }
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -4;
+ goto bail;
+ }
+ if (!(pc_peer = (tnet_turn_peer_t *)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
+ TSK_DEBUG_ERROR("Cannot find TURN peer with id = %ld", u_peer_id);
+ ret = -5;
+ goto bail;
+ }
- // Connect must be used for streams (e.g. TCP, TLS....) only
- if (p_self->e_req_transport != tnet_turn_transport_tcp) {
- TSK_DEBUG_ERROR("TURN Connect not supported for UDP relay");
- ret = -6;
- goto bail;
- }
+ // Connect must be used for streams (e.g. TCP, TLS....) only
+ if (p_self->e_req_transport != tnet_turn_transport_tcp) {
+ TSK_DEBUG_ERROR("TURN Connect not supported for UDP relay");
+ ret = -6;
+ goto bail;
+ }
- // create Connect Request if doesn't exist (Connect refresh *must* have same id)
- pc_peer->e_connect_state = tnet_stun_state_none;
- pc_peer->e_connbind_state = tnet_stun_state_none;
- if (!pc_peer->p_pkt_connect) {
- if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_connect_request, &pc_peer->p_pkt_connect))) {
- TSK_DEBUG_ERROR("Failed to create TURN Connect request");
- goto bail;
- }
- // add authentication info
- tnet_stun_pkt_auth_copy(pc_peer->p_pkt_connect, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
- // add attributes
- pc_peer->p_pkt_connect->opt.dontfrag = 0;
- ret = tnet_stun_pkt_attrs_add(pc_peer->p_pkt_connect,
- /* Must not add LIFETIME and there is no way to delete permission */
- TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(pc_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, pc_peer->u_addr_port, &pc_peer->addr_ip),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
-
- }
- else {
- if ((ret = tnet_stun_utils_transac_id_rand(&pc_peer->p_pkt_connect->transac_id))) {
- goto bail;
- }
- }
-
- if ((ret = _tnet_turn_session_send_pkt(p_self, pc_peer->p_pkt_connect))) {
- goto bail;
- }
- pc_peer->e_connect_state = tnet_stun_state_trying;
+ // create Connect Request if doesn't exist (Connect refresh *must* have same id)
+ pc_peer->e_connect_state = tnet_stun_state_none;
+ pc_peer->e_connbind_state = tnet_stun_state_none;
+ if (!pc_peer->p_pkt_connect) {
+ if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_connect_request, &pc_peer->p_pkt_connect))) {
+ TSK_DEBUG_ERROR("Failed to create TURN Connect request");
+ goto bail;
+ }
+ // add authentication info
+ tnet_stun_pkt_auth_copy(pc_peer->p_pkt_connect, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
+ // add attributes
+ pc_peer->p_pkt_connect->opt.dontfrag = 0;
+ ret = tnet_stun_pkt_attrs_add(pc_peer->p_pkt_connect,
+ /* Must not add LIFETIME and there is no way to delete permission */
+ TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(pc_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, pc_peer->u_addr_port, &pc_peer->addr_ip),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+
+ }
+ else {
+ if ((ret = tnet_stun_utils_transac_id_rand(&pc_peer->p_pkt_connect->transac_id))) {
+ goto bail;
+ }
+ }
+
+ if ((ret = _tnet_turn_session_send_pkt(p_self, pc_peer->p_pkt_connect))) {
+ goto bail;
+ }
+ pc_peer->e_connect_state = tnet_stun_state_trying;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
int tnet_turn_session_send_data(tnet_turn_session_t* p_self, tnet_turn_peer_id_t u_peer_id, const void* pc_data_ptr, uint16_t u_data_size)
{
- int ret = 0;
- tnet_turn_peer_t* pc_peer;
+ int ret = 0;
+ tnet_turn_peer_t* pc_peer;
- if (!p_self || !pc_data_ptr || !u_data_size) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self || !pc_data_ptr || !u_data_size) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -3;
- goto bail;
- }
- if (!(pc_peer = (tnet_turn_peer_t *)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
- TSK_DEBUG_ERROR("Cannot find TURN peer with id = %ld", u_peer_id);
- ret = -4;
- goto bail;
- }
- if (pc_peer->e_createperm_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN permission for the remote peer");
- ret = -5;
- goto bail;
- }
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -3;
+ goto bail;
+ }
+ if (!(pc_peer = (tnet_turn_peer_t *)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
+ TSK_DEBUG_ERROR("Cannot find TURN peer with id = %ld", u_peer_id);
+ ret = -4;
+ goto bail;
+ }
+ if (pc_peer->e_createperm_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN permission for the remote peer");
+ ret = -5;
+ goto bail;
+ }
- /** Send Stream **/
- if (TNET_SOCKET_TYPE_IS_STREAM(p_self->p_lcl_sock->type) && p_self->e_req_transport == tnet_turn_transport_tcp) {
- ret = _tnet_turn_session_send_stream_raw(p_self, pc_peer, pc_data_ptr, u_data_size);
- goto bail;
- }
+ /** Send Stream **/
+ if (TNET_SOCKET_TYPE_IS_STREAM(p_self->p_lcl_sock->type) && p_self->e_req_transport == tnet_turn_transport_tcp) {
+ ret = _tnet_turn_session_send_stream_raw(p_self, pc_peer, pc_data_ptr, u_data_size);
+ goto bail;
+ }
- /*** ChannelData ***/
- if (pc_peer->e_chanbind_state == tnet_stun_state_ok) {
- ret = _tnet_turn_session_send_chandata(p_self, pc_peer, pc_data_ptr, u_data_size);
- goto bail;
- }
+ /*** ChannelData ***/
+ if (pc_peer->e_chanbind_state == tnet_stun_state_ok) {
+ ret = _tnet_turn_session_send_chandata(p_self, pc_peer, pc_data_ptr, u_data_size);
+ goto bail;
+ }
+
+ /*** Send indication ***/
+ if (!pc_peer->p_pkt_sendind) {
+ if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_send_indication, &pc_peer->p_pkt_sendind))) {
+ TSK_DEBUG_ERROR("Failed to create TURN SendIndication request");
+ goto bail;
+ }
+ pc_peer->p_pkt_sendind->opt.dontfrag = 0;
+ // add authinfo
+ tnet_stun_pkt_auth_copy(pc_peer->p_pkt_sendind, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
+ // add attributes
+ ret = tnet_stun_pkt_attrs_add(pc_peer->p_pkt_sendind,
+ TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(pc_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, pc_peer->u_addr_port, &pc_peer->addr_ip),
+ TNET_STUN_PKT_ATTR_ADD_DATA(pc_data_ptr, u_data_size),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ else {
+ const tnet_stun_attr_vdata_t *pc_attr_data;
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_peer->p_pkt_sendind, tnet_stun_attr_type_data, (const tnet_stun_attr_t**)&pc_attr_data))) {
+ goto bail;
+ }
+ if (!pc_attr_data) {
+ ret = tnet_stun_pkt_attrs_add(pc_peer->p_pkt_sendind,
+ TNET_STUN_PKT_ATTR_ADD_DATA(pc_data_ptr, u_data_size),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ }
+ else {
+ if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr_data, pc_data_ptr, u_data_size))) {
+ goto bail;
+ }
+ }
+ if ((ret = tnet_stun_utils_transac_id_rand(&pc_peer->p_pkt_sendind->transac_id))) {
+ goto bail;
+ }
+ }
+ if ((ret = _tnet_turn_session_send_pkt_0(p_self, pc_peer, pc_peer->p_pkt_sendind))) {
+ goto bail;
+ }
- /*** Send indication ***/
- if (!pc_peer->p_pkt_sendind) {
- if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_send_indication, &pc_peer->p_pkt_sendind))) {
- TSK_DEBUG_ERROR("Failed to create TURN SendIndication request");
- goto bail;
- }
- pc_peer->p_pkt_sendind->opt.dontfrag = 0;
- // add authinfo
- tnet_stun_pkt_auth_copy(pc_peer->p_pkt_sendind, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
- // add attributes
- ret = tnet_stun_pkt_attrs_add(pc_peer->p_pkt_sendind,
- TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(pc_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, pc_peer->u_addr_port, &pc_peer->addr_ip),
- TNET_STUN_PKT_ATTR_ADD_DATA(pc_data_ptr, u_data_size),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- else {
- const tnet_stun_attr_vdata_t *pc_attr_data;
- if ((ret = tnet_stun_pkt_attr_find_first(pc_peer->p_pkt_sendind, tnet_stun_attr_type_data, (const tnet_stun_attr_t**)&pc_attr_data))) {
- goto bail;
- }
- if (!pc_attr_data) {
- ret = tnet_stun_pkt_attrs_add(pc_peer->p_pkt_sendind,
- TNET_STUN_PKT_ATTR_ADD_DATA(pc_data_ptr, u_data_size),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- }
- else {
- if ((ret = tnet_stun_attr_vdata_update((tnet_stun_attr_vdata_t*)pc_attr_data, pc_data_ptr, u_data_size))) {
- goto bail;
- }
- }
- if ((ret = tnet_stun_utils_transac_id_rand(&pc_peer->p_pkt_sendind->transac_id))) {
- goto bail;
- }
- }
- if ((ret = _tnet_turn_session_send_pkt_0(p_self, pc_peer, pc_peer->p_pkt_sendind))) {
- goto bail;
- }
-
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
int tnet_turn_session_is_active(const struct tnet_turn_session_s* pc_self, tnet_turn_peer_id_t u_peer_id, tsk_bool_t *pb_active)
{
- if (!pc_self || !pb_active) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(pc_self);
- *pb_active = pc_self->b_started
- && (pc_self->e_alloc_state == tnet_stun_state_ok);
- if (*pb_active) {
- const tnet_turn_peer_t* pc_peer;
- if ((pc_peer = (const tnet_turn_peer_t *)tsk_list_find_object_by_pred(pc_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
- *pb_active = (pc_peer->e_createperm_state == tnet_stun_state_ok);
- }
- else {
- *pb_active = tsk_false;
- }
- }
- tsk_safeobj_unlock(pc_self);
- return 0;
+ if (!pc_self || !pb_active) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(pc_self);
+ *pb_active = pc_self->b_started
+ && (pc_self->e_alloc_state == tnet_stun_state_ok);
+ if (*pb_active) {
+ const tnet_turn_peer_t* pc_peer;
+ if ((pc_peer = (const tnet_turn_peer_t *)tsk_list_find_object_by_pred(pc_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
+ *pb_active = (pc_peer->e_createperm_state == tnet_stun_state_ok);
+ }
+ else {
+ *pb_active = tsk_false;
+ }
+ }
+ tsk_safeobj_unlock(pc_self);
+ return 0;
}
int tnet_turn_session_is_stream(const struct tnet_turn_session_s* pc_self, tsk_bool_t *pb_stream)
{
- if (!pc_self || !pb_stream) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(pc_self);
- *pb_stream = TNET_SOCKET_TYPE_IS_STREAM(pc_self->p_lcl_sock->type) ? tsk_true : tsk_false;
- tsk_safeobj_unlock(pc_self);
- return 0;
+ if (!pc_self || !pb_stream) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(pc_self);
+ *pb_stream = TNET_SOCKET_TYPE_IS_STREAM(pc_self->p_lcl_sock->type) ? tsk_true : tsk_false;
+ tsk_safeobj_unlock(pc_self);
+ return 0;
}
// Check "ConnectionBind" sent and underlaying socket is connected
int tnet_turn_session_is_stream_connected(const struct tnet_turn_session_s* pc_self, tnet_turn_peer_id_t u_peer_id, tsk_bool_t *pb_connected)
{
- if (!pc_self || !pb_connected) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- tsk_safeobj_lock(pc_self);
- *pb_connected = pc_self->b_started
- && (pc_self->e_alloc_state == tnet_stun_state_ok);
- if (*pb_connected) {
- const tnet_turn_peer_t* pc_peer;
- if ((pc_peer = (const tnet_turn_peer_t *)tsk_list_find_object_by_pred(pc_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
- *pb_connected = (pc_peer->conn_fd != TNET_INVALID_FD && pc_peer->b_stream_connected && pc_peer->e_connbind_state == tnet_stun_state_ok);
- }
- else {
- *pb_connected = tsk_false;
- }
- }
- tsk_safeobj_unlock(pc_self);
- return 0;
+ if (!pc_self || !pb_connected) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ tsk_safeobj_lock(pc_self);
+ *pb_connected = pc_self->b_started
+ && (pc_self->e_alloc_state == tnet_stun_state_ok);
+ if (*pb_connected) {
+ const tnet_turn_peer_t* pc_peer;
+ if ((pc_peer = (const tnet_turn_peer_t *)tsk_list_find_object_by_pred(pc_self->p_list_peers, __pred_find_peer_by_id, &u_peer_id))) {
+ *pb_connected = (pc_peer->conn_fd != TNET_INVALID_FD && pc_peer->b_stream_connected && pc_peer->e_connbind_state == tnet_stun_state_ok);
+ }
+ else {
+ *pb_connected = tsk_false;
+ }
+ }
+ tsk_safeobj_unlock(pc_self);
+ return 0;
}
int tnet_turn_session_stop(tnet_turn_session_t* p_self)
{
- int ret = 0;
+ int ret = 0;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- // FIXME
- // tsk_safeobj_lock(p_self);
+ // FIXME
+ // tsk_safeobj_lock(p_self);
- p_self->b_stopping = tsk_true;
+ p_self->b_stopping = tsk_true;
- if (p_self->e_alloc_state == tnet_stun_state_ok) {
- // UnAlloc
- p_self->u_lifetime_alloc_in_sec = 0;
- _tnet_turn_session_send_refresh(p_self);
- }
+ if (p_self->e_alloc_state == tnet_stun_state_ok) {
+ // UnAlloc
+ p_self->u_lifetime_alloc_in_sec = 0;
+ _tnet_turn_session_send_refresh(p_self);
+ }
- if (p_self->timer.p_mgr) {
- ret = tsk_timer_manager_stop(p_self->timer.p_mgr);
- }
+ if (p_self->timer.p_mgr) {
+ ret = tsk_timer_manager_stop(p_self->timer.p_mgr);
+ }
- // free transport to force next call to prepare() to create new one with new sockets
+ // free transport to force next call to prepare() to create new one with new sockets
if (p_self->p_transport) {
tnet_transport_shutdown(p_self->p_transport);
TSK_OBJECT_SAFE_FREE(p_self->p_transport);
}
- // clear peers
- tsk_list_clear_items(p_self->p_list_peers);
+ // clear peers
+ tsk_list_clear_items(p_self->p_list_peers);
- p_self->b_prepared = tsk_false;
- p_self->b_started = tsk_false;
- p_self->b_stopping = tsk_false;
+ p_self->b_prepared = tsk_false;
+ p_self->b_started = tsk_false;
+ p_self->b_stopping = tsk_false;
- // tsk_safeobj_unlock(p_self);
+ // tsk_safeobj_unlock(p_self);
- return ret;
+ return ret;
}
static int _tnet_turn_session_peer_find_by_id(const tnet_turn_session_t* pc_self, tnet_turn_peer_id_t id, const struct tnet_turn_peer_s **ppc_peer)
{
- const tsk_list_item_t *pc_item;
- const struct tnet_turn_peer_s *pc_peer;
- if (!pc_self || !ppc_peer) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *ppc_peer = tsk_null;
- tsk_list_foreach(pc_item, pc_self->p_list_peers) {
- if (!(pc_peer = pc_item->data)) {
- continue;
- }
- if (pc_peer->id == id) {
- *ppc_peer = pc_peer;
- break;
- }
- }
- return 0;
+ const tsk_list_item_t *pc_item;
+ const struct tnet_turn_peer_s *pc_peer;
+ if (!pc_self || !ppc_peer) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *ppc_peer = tsk_null;
+ tsk_list_foreach(pc_item, pc_self->p_list_peers) {
+ if (!(pc_peer = pc_item->data)) {
+ continue;
+ }
+ if (pc_peer->id == id) {
+ *ppc_peer = pc_peer;
+ break;
+ }
+ }
+ return 0;
}
static int _tnet_turn_session_peer_find_by_timer(const tnet_turn_session_t* pc_self, tsk_timer_id_t id, const struct tnet_turn_peer_s **ppc_peer)
{
- const tsk_list_item_t *pc_item;
- const struct tnet_turn_peer_s *pc_peer;
- if (!pc_self || !ppc_peer) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *ppc_peer = tsk_null;
- tsk_list_foreach(pc_item, pc_self->p_list_peers) {
- if (!(pc_peer = pc_item->data)) {
- continue;
- }
- if (pc_peer->timer.rtt.chanbind.id == id || pc_peer->timer.rtt.createperm.id == id) {
- *ppc_peer = pc_peer;
- break;
- }
- }
- return 0;
+ const tsk_list_item_t *pc_item;
+ const struct tnet_turn_peer_s *pc_peer;
+ if (!pc_self || !ppc_peer) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *ppc_peer = tsk_null;
+ tsk_list_foreach(pc_item, pc_self->p_list_peers) {
+ if (!(pc_peer = pc_item->data)) {
+ continue;
+ }
+ if (pc_peer->timer.rtt.chanbind.id == id || pc_peer->timer.rtt.createperm.id == id) {
+ *ppc_peer = pc_peer;
+ break;
+ }
+ }
+ return 0;
}
static uint16_t _tnet_turn_session_get_unique_chan_num()
{
- // rfc5766 - The channel number is in the range 0x4000 through 0x7FFE (inclusive)
- static long __l_chan_num = 0;
- tsk_atomic_inc(&__l_chan_num);
- return (__l_chan_num % (0x7FFE - 0x4000)) + 0x4000;
+ // rfc5766 - The channel number is in the range 0x4000 through 0x7FFE (inclusive)
+ static long __l_chan_num = 0;
+ tsk_atomic_inc(&__l_chan_num);
+ return (__l_chan_num % (0x7FFE - 0x4000)) + 0x4000;
}
static int _tnet_turn_session_send_chandata(tnet_turn_session_t* p_self, const tnet_turn_peer_t* pc_peer, const void* pc_buff_ptr, tsk_size_t u_buff_size)
{
- int ret = 0;
- tsk_size_t PadSize, NeededSize;
- uint8_t* _p_buff_chandata_ptr;
+ int ret = 0;
+ tsk_size_t PadSize, NeededSize;
+ uint8_t* _p_buff_chandata_ptr;
if (!p_self || !pc_peer || !pc_buff_ptr || !u_buff_size) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
@@ -1257,45 +1267,45 @@ static int _tnet_turn_session_send_chandata(tnet_turn_session_t* p_self, const t
ret = -2;
goto bail;
}
- if (pc_peer->e_chanbind_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN data channel for peer id = %ld", pc_peer->id);
+ if (pc_peer->e_chanbind_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN data channel for peer id = %ld", pc_peer->id);
ret = -3;
goto bail;
}
- // rfc5766 - 11.5. Sending a ChannelData Message
- if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
- // Over UDP, the padding is not required but MAY be included.
- PadSize = 0;
- }
- else {
- // Over TCP and TLS-over-TCP, the ChannelData message MUST be padded to
- // a multiple of four bytes in order to ensure the alignment of subsequent messages.
- PadSize = (u_buff_size & 0x03) ? (4 - (u_buff_size & 0x03)) : 0;
- }
- NeededSize = kStunChannelDataHdrSizeInOctets + u_buff_size + PadSize;
-
- if (p_self->u_buff_chandata_size < NeededSize) {
- if (!(p_self->p_buff_chandata_ptr = tsk_realloc(p_self->p_buff_chandata_ptr, NeededSize))) {
- p_self->u_buff_chandata_size = 0;
- ret = -4;
- goto bail;
- }
- p_self->u_buff_chandata_size = NeededSize;
- }
- _p_buff_chandata_ptr = (uint8_t*)p_self->p_buff_chandata_ptr;
+ // rfc5766 - 11.5. Sending a ChannelData Message
+ if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
+ // Over UDP, the padding is not required but MAY be included.
+ PadSize = 0;
+ }
+ else {
+ // Over TCP and TLS-over-TCP, the ChannelData message MUST be padded to
+ // a multiple of four bytes in order to ensure the alignment of subsequent messages.
+ PadSize = (u_buff_size & 0x03) ? (4 - (u_buff_size & 0x03)) : 0;
+ }
+ NeededSize = kStunChannelDataHdrSizeInOctets + u_buff_size + PadSize;
- *((uint16_t*)&_p_buff_chandata_ptr[0]) = tnet_htons(pc_peer->u_chan_num); // Channel Number
- *((uint16_t*)&_p_buff_chandata_ptr[2]) = tnet_htons((uint16_t)u_buff_size); // Length
- memcpy(&_p_buff_chandata_ptr[kStunChannelDataHdrSizeInOctets], pc_buff_ptr, u_buff_size); // Application Data
- if (PadSize) {
- memset(&_p_buff_chandata_ptr[kStunChannelDataHdrSizeInOctets + u_buff_size], 0, PadSize); // Set padding bytes to zero (not required but ease debugging)
- }
+ if (p_self->u_buff_chandata_size < NeededSize) {
+ if (!(p_self->p_buff_chandata_ptr = tsk_realloc(p_self->p_buff_chandata_ptr, NeededSize))) {
+ p_self->u_buff_chandata_size = 0;
+ ret = -4;
+ goto bail;
+ }
+ p_self->u_buff_chandata_size = NeededSize;
+ }
+ _p_buff_chandata_ptr = (uint8_t*)p_self->p_buff_chandata_ptr;
+
+ *((uint16_t*)&_p_buff_chandata_ptr[0]) = tnet_htons(pc_peer->u_chan_num); // Channel Number
+ *((uint16_t*)&_p_buff_chandata_ptr[2]) = tnet_htons((uint16_t)u_buff_size); // Length
+ memcpy(&_p_buff_chandata_ptr[kStunChannelDataHdrSizeInOctets], pc_buff_ptr, u_buff_size); // Application Data
+ if (PadSize) {
+ memset(&_p_buff_chandata_ptr[kStunChannelDataHdrSizeInOctets + u_buff_size], 0, PadSize); // Set padding bytes to zero (not required but ease debugging)
+ }
+
+ if ((ret = _tnet_turn_session_send_buff_0(p_self, pc_peer, p_self->p_buff_chandata_ptr, NeededSize))) {
+ goto bail;
+ }
- if ((ret = _tnet_turn_session_send_buff_0(p_self, pc_peer, p_self->p_buff_chandata_ptr, NeededSize))) {
- goto bail;
- }
-
bail:
// unlock()
tsk_safeobj_unlock(p_self);
@@ -1304,7 +1314,7 @@ bail:
static int _tnet_turn_session_send_stream_raw(tnet_turn_session_t* p_self, tnet_turn_peer_t* pc_peer, const void* pc_buff_ptr, tsk_size_t u_buff_size)
{
- int ret = 0;
+ int ret = 0;
if (!p_self || !pc_peer || !pc_buff_ptr || !u_buff_size) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
@@ -1318,20 +1328,20 @@ static int _tnet_turn_session_send_stream_raw(tnet_turn_session_t* p_self, tnet_
ret = -2;
goto bail;
}
- if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
- TSK_DEBUG_ERROR("Must not call this function for non-stream transports");
+ if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
+ TSK_DEBUG_ERROR("Must not call this function for non-stream transports");
ret = -3;
goto bail;
- }
- if (pc_peer->e_connbind_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN TCP connection for peer id = %ld", pc_peer->id);
+ }
+ if (pc_peer->e_connbind_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN TCP connection for peer id = %ld", pc_peer->id);
ret = -4;
goto bail;
}
- if ((ret = _tnet_turn_session_send_buff_0(p_self, pc_peer, pc_buff_ptr, u_buff_size))) {
- goto bail;
- }
+ if ((ret = _tnet_turn_session_send_buff_0(p_self, pc_peer, pc_buff_ptr, u_buff_size))) {
+ goto bail;
+ }
bail:
// unlock()
@@ -1341,202 +1351,202 @@ bail:
static int _tnet_turn_session_send_refresh(tnet_turn_session_t* p_self)
{
- int ret = 0;
+ int ret = 0;
- if (!p_self) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -4;
- goto bail;
- }
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -4;
+ goto bail;
+ }
- p_self->e_refresh_state = tnet_stun_state_none;
- // create RefreshIndication Request
- p_self->timer.rtt.refresh.id = TSK_INVALID_TIMER_ID;
- TSK_OBJECT_SAFE_FREE(p_self->p_pkt_refresh);
- if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_refresh_request, &p_self->p_pkt_refresh))) {
- TSK_DEBUG_ERROR("Failed to create TURN RefreshIndication request");
- goto bail;
- }
- // add authentication info
- tnet_stun_pkt_auth_copy(p_self->p_pkt_refresh, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
+ p_self->e_refresh_state = tnet_stun_state_none;
+ // create RefreshIndication Request
+ p_self->timer.rtt.refresh.id = TSK_INVALID_TIMER_ID;
+ TSK_OBJECT_SAFE_FREE(p_self->p_pkt_refresh);
+ if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_refresh_request, &p_self->p_pkt_refresh))) {
+ TSK_DEBUG_ERROR("Failed to create TURN RefreshIndication request");
+ goto bail;
+ }
+ // add authentication info
+ tnet_stun_pkt_auth_copy(p_self->p_pkt_refresh, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
#if 0
- if (p_self->u_lifetime_alloc_in_sec == 0) {
- const tnet_stun_attr_vdata_t *pc_attr_nonce = tsk_null;
- tnet_stun_pkt_attr_find_first(p_self->p_pkt_refresh, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce);
- if (pc_attr_nonce) {
- pc_attr_nonce->p_data_ptr[0] = 'a';
- }
- }
+ if (p_self->u_lifetime_alloc_in_sec == 0) {
+ const tnet_stun_attr_vdata_t *pc_attr_nonce = tsk_null;
+ tnet_stun_pkt_attr_find_first(p_self->p_pkt_refresh, tnet_stun_attr_type_nonce, (const tnet_stun_attr_t**)&pc_attr_nonce);
+ if (pc_attr_nonce) {
+ pc_attr_nonce->p_data_ptr[0] = 'a';
+ }
+ }
#endif
- // add attributes
- ret = tnet_stun_pkt_attrs_add(p_self->p_pkt_refresh,
- TNET_STUN_PKT_ATTR_ADD_LIFETIME(p_self->u_lifetime_alloc_in_sec),
- TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware), // recommended for Alloc and Refresh
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
- p_self->p_pkt_refresh->opt.dontfrag = 0;
- p_self->p_pkt_refresh->opt.fingerprint = 0;
- if ((ret = _tnet_turn_session_send_pkt(p_self, p_self->p_pkt_refresh))) {
- goto bail;
- }
- if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
- p_self->timer.rtt.refresh.u_timeout = kStunUdpRetransmitTimoutMinInMs;
- TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, p_self->timer.rtt.refresh.id, p_self->timer.rtt.refresh.u_timeout);
- }
- p_self->e_refresh_state = tnet_stun_state_trying;
+ // add attributes
+ ret = tnet_stun_pkt_attrs_add(p_self->p_pkt_refresh,
+ TNET_STUN_PKT_ATTR_ADD_LIFETIME(p_self->u_lifetime_alloc_in_sec),
+ TNET_STUN_PKT_ATTR_ADD_SOFTWARE_ZT(kStunSoftware), // recommended for Alloc and Refresh
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+ p_self->p_pkt_refresh->opt.dontfrag = 0;
+ p_self->p_pkt_refresh->opt.fingerprint = 0;
+ if ((ret = _tnet_turn_session_send_pkt(p_self, p_self->p_pkt_refresh))) {
+ goto bail;
+ }
+ if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
+ p_self->timer.rtt.refresh.u_timeout = kStunUdpRetransmitTimoutMinInMs;
+ TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, p_self->timer.rtt.refresh.id, p_self->timer.rtt.refresh.u_timeout);
+ }
+ p_self->e_refresh_state = tnet_stun_state_trying;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
static int _tnet_turn_session_send_permission(struct tnet_turn_session_s* p_self, tnet_turn_peer_t *p_peer)
{
- int ret = 0;
- if (!p_self || !p_peer) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
-
- tsk_safeobj_lock(p_self);
+ int ret = 0;
+ if (!p_self || !p_peer) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -4;
- goto bail;
- }
+ tsk_safeobj_lock(p_self);
- // create CreatePermission Request
- p_peer->e_createperm_state = tnet_stun_state_none;
- p_peer->timer.rtt.createperm.id = TSK_INVALID_TIMER_ID;
- TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_createperm);
- if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_createpermission_request, &p_peer->p_pkt_createperm))) {
- TSK_DEBUG_ERROR("Failed to create TURN CreatePermission request");
- goto bail;
- }
- // add authinfo
- tnet_stun_pkt_auth_copy(p_peer->p_pkt_createperm, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
- // add attributes
- p_peer->p_pkt_createperm->opt.dontfrag = 0;
- ret = tnet_stun_pkt_attrs_add(p_peer->p_pkt_createperm,
- /* Must not add LIFETIME and there is no way to delete permission */
- TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(p_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, p_peer->u_addr_port, &p_peer->addr_ip),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
-
- if ((ret = _tnet_turn_session_send_pkt(p_self, p_peer->p_pkt_createperm))) {
- goto bail;
- }
- if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
- p_peer->timer.rtt.createperm.u_timeout = kStunUdpRetransmitTimoutMinInMs;
- TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, p_peer->timer.rtt.createperm.id, p_peer->timer.rtt.createperm.u_timeout);
- }
- p_peer->e_createperm_state = tnet_stun_state_trying;
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -4;
+ goto bail;
+ }
+
+ // create CreatePermission Request
+ p_peer->e_createperm_state = tnet_stun_state_none;
+ p_peer->timer.rtt.createperm.id = TSK_INVALID_TIMER_ID;
+ TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_createperm);
+ if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_createpermission_request, &p_peer->p_pkt_createperm))) {
+ TSK_DEBUG_ERROR("Failed to create TURN CreatePermission request");
+ goto bail;
+ }
+ // add authinfo
+ tnet_stun_pkt_auth_copy(p_peer->p_pkt_createperm, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
+ // add attributes
+ p_peer->p_pkt_createperm->opt.dontfrag = 0;
+ ret = tnet_stun_pkt_attrs_add(p_peer->p_pkt_createperm,
+ /* Must not add LIFETIME and there is no way to delete permission */
+ TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(p_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, p_peer->u_addr_port, &p_peer->addr_ip),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+
+ if ((ret = _tnet_turn_session_send_pkt(p_self, p_peer->p_pkt_createperm))) {
+ goto bail;
+ }
+ if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
+ p_peer->timer.rtt.createperm.u_timeout = kStunUdpRetransmitTimoutMinInMs;
+ TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, p_peer->timer.rtt.createperm.id, p_peer->timer.rtt.createperm.u_timeout);
+ }
+ p_peer->e_createperm_state = tnet_stun_state_trying;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
// TCP-Connect rfc6062 - 4.3. Initiating a Connection
static int _tnet_turn_session_send_connbind(struct tnet_turn_session_s* p_self, tnet_turn_peer_t *p_peer)
{
- int ret = 0;
+ int ret = 0;
- if (!p_self || !p_peer) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ if (!p_self || !p_peer) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if (!p_self->b_started) {
- TSK_DEBUG_ERROR("TURN session not started yet");
- ret = -3;
- goto bail;
- }
- if (p_self->e_alloc_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN allocation yet");
- ret = -4;
- goto bail;
- }
+ if (!p_self->b_started) {
+ TSK_DEBUG_ERROR("TURN session not started yet");
+ ret = -3;
+ goto bail;
+ }
+ if (p_self->e_alloc_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN allocation yet");
+ ret = -4;
+ goto bail;
+ }
- // ConnectionBind must be sent after Connect
- if (p_peer->e_connect_state != tnet_stun_state_ok) {
- TSK_DEBUG_ERROR("No active TURN connection yet");
- ret = -6;
- goto bail;
- }
-
- // Connect must be used for streams (e.g. TCP, TLS....) only
- if (p_self->e_req_transport != tnet_turn_transport_tcp) {
- TSK_DEBUG_ERROR("TURN ConnectionBind not supported for UDP transport");
- ret = -7;
- goto bail;
- }
+ // ConnectionBind must be sent after Connect
+ if (p_peer->e_connect_state != tnet_stun_state_ok) {
+ TSK_DEBUG_ERROR("No active TURN connection yet");
+ ret = -6;
+ goto bail;
+ }
- // create Connect Request if doesn't exist (Connect refresh *must* have same id)
- p_peer->e_connbind_state = tnet_stun_state_none;
- if (!p_peer->p_pkt_connbind) {
- if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_connectionbind_request, &p_peer->p_pkt_connbind))) {
- TSK_DEBUG_ERROR("Failed to create TURN ConnectionBind request");
- goto bail;
- }
- // add authentication info
- tnet_stun_pkt_auth_copy(p_peer->p_pkt_connbind, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
- // add attributes
- p_peer->p_pkt_connbind->opt.dontfrag = 0;
- ret = tnet_stun_pkt_attrs_add(p_peer->p_pkt_connbind,
- // Error "420" when XOR-PEER-ADDRESS attribute is added to ConnectionBind request
- /* TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(p_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, p_peer->u_addr_port, &p_peer->addr_ip), */
- TNET_STUN_PKT_ATTR_ADD_CONNECTION_ID(p_peer->u_conn_id),
- TNET_STUN_PKT_ATTR_ADD_NULL());
- if (ret) {
- goto bail;
- }
-
- }
- else {
- if ((ret = tnet_stun_utils_transac_id_rand(&p_peer->p_pkt_connbind->transac_id))) {
- goto bail;
- }
- }
-
- if ((ret = _tnet_turn_session_send_pkt_0(p_self, p_peer, p_peer->p_pkt_connbind))) {
- goto bail;
- }
- p_peer->e_connbind_state = tnet_stun_state_trying;
+ // Connect must be used for streams (e.g. TCP, TLS....) only
+ if (p_self->e_req_transport != tnet_turn_transport_tcp) {
+ TSK_DEBUG_ERROR("TURN ConnectionBind not supported for UDP transport");
+ ret = -7;
+ goto bail;
+ }
+
+ // create Connect Request if doesn't exist (Connect refresh *must* have same id)
+ p_peer->e_connbind_state = tnet_stun_state_none;
+ if (!p_peer->p_pkt_connbind) {
+ if ((ret = tnet_stun_pkt_create_empty(tnet_stun_pkt_type_connectionbind_request, &p_peer->p_pkt_connbind))) {
+ TSK_DEBUG_ERROR("Failed to create TURN ConnectionBind request");
+ goto bail;
+ }
+ // add authentication info
+ tnet_stun_pkt_auth_copy(p_peer->p_pkt_connbind, p_self->cred.p_usr_name, p_self->cred.p_pwd, p_self->p_pkt_alloc);
+ // add attributes
+ p_peer->p_pkt_connbind->opt.dontfrag = 0;
+ ret = tnet_stun_pkt_attrs_add(p_peer->p_pkt_connbind,
+ // Error "420" when XOR-PEER-ADDRESS attribute is added to ConnectionBind request
+ /* TNET_STUN_PKT_ATTR_ADD_XOR_PEER_ADDRESS(p_peer->b_ipv6 ? tnet_stun_address_family_ipv6 : tnet_stun_address_family_ipv4, p_peer->u_addr_port, &p_peer->addr_ip), */
+ TNET_STUN_PKT_ATTR_ADD_CONNECTION_ID(p_peer->u_conn_id),
+ TNET_STUN_PKT_ATTR_ADD_NULL());
+ if (ret) {
+ goto bail;
+ }
+
+ }
+ else {
+ if ((ret = tnet_stun_utils_transac_id_rand(&p_peer->p_pkt_connbind->transac_id))) {
+ goto bail;
+ }
+ }
+
+ if ((ret = _tnet_turn_session_send_pkt_0(p_self, p_peer, p_peer->p_pkt_connbind))) {
+ goto bail;
+ }
+ p_peer->e_connbind_state = tnet_stun_state_trying;
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
static int _tnet_turn_session_send_buff_0(tnet_turn_session_t* p_self, const tnet_turn_peer_t* pc_peer, const void* pc_buff_ptr, tsk_size_t u_buff_size)
{
int ret = 0;
- tsk_size_t u_sent_bytes = 0;
+ tsk_size_t u_sent_bytes = 0;
if (!p_self || !pc_buff_ptr || !u_buff_size) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
@@ -1551,28 +1561,28 @@ static int _tnet_turn_session_send_buff_0(tnet_turn_session_t* p_self, const tne
goto bail;
}
- if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
+ if (TNET_SOCKET_TYPE_IS_DGRAM(p_self->p_lcl_sock->type)) {
#if 1
- u_sent_bytes = tnet_transport_sendto(p_self->p_transport, p_self->p_lcl_sock->fd, (const struct sockaddr *)&p_self->srv_addr, pc_buff_ptr, u_buff_size);
+ u_sent_bytes = tnet_transport_sendto(p_self->p_transport, p_self->p_lcl_sock->fd, (const struct sockaddr *)&p_self->srv_addr, pc_buff_ptr, u_buff_size);
#else
- u_sent_bytes = tnet_sockfd_sendto(p_self->p_lcl_sock->fd, (const struct sockaddr *)&p_self->srv_addr, pc_buff_ptr, u_buff_size);
+ u_sent_bytes = tnet_sockfd_sendto(p_self->p_lcl_sock->fd, (const struct sockaddr *)&p_self->srv_addr, pc_buff_ptr, u_buff_size);
#endif
}
else {
- if (pc_peer && pc_peer->b_stream_connected && pc_peer->conn_fd != TNET_INVALID_FD) {
- // Send using Peer connection if connected
- // Should never be called because for now requested transport is always equal to UDP
+ if (pc_peer && pc_peer->b_stream_connected && pc_peer->conn_fd != TNET_INVALID_FD) {
+ // Send using Peer connection if connected
+ // Should never be called because for now requested transport is always equal to UDP
#if 1
- u_sent_bytes = tnet_transport_send(p_self->p_transport, pc_peer->conn_fd, pc_buff_ptr, u_buff_size);
+ u_sent_bytes = tnet_transport_send(p_self->p_transport, pc_peer->conn_fd, pc_buff_ptr, u_buff_size);
#else
- u_sent_bytes = tnet_sockfd_send(pc_peer->conn_fd, pc_buff_ptr, u_buff_size, 0);
+ u_sent_bytes = tnet_sockfd_send(pc_peer->conn_fd, pc_buff_ptr, u_buff_size, 0);
#endif
- }
- else {
+ }
+ else {
tsk_bool_t b_delay_send = tsk_false;
- // Connect if not already done
- if (!p_self->b_stream_connected) {
- ret = tnet_sockfd_waitUntilWritable(p_self->p_lcl_sock->fd, kTurnTransportConnectTimeout);
+ // Connect if not already done
+ if (!p_self->b_stream_connected) {
+ ret = tnet_sockfd_waitUntilWritable(p_self->p_lcl_sock->fd, kTurnTransportConnectTimeout);
if (ret == 0) { // socket is valid but not connected (e.g. Proxy handshaking not completed yet)
TSK_DEBUG_INFO("Saving %u TURN bytes and waiting for 'connected' event before sending", (unsigned)u_buff_size);
if (!p_self->p_stream_buff_out && !(p_self->p_stream_buff_out = tsk_buffer_create_null())) {
@@ -1594,17 +1604,17 @@ static int _tnet_turn_session_send_buff_0(tnet_turn_session_t* p_self, const tne
ret = -6;
goto bail;
}
- }
- if (!b_delay_send && p_self->b_stream_connected) {
+ }
+ if (!b_delay_send && p_self->b_stream_connected) {
#if 1
- u_sent_bytes = tnet_transport_send(p_self->p_transport, p_self->p_lcl_sock->fd, pc_buff_ptr, u_buff_size);
+ u_sent_bytes = tnet_transport_send(p_self->p_transport, p_self->p_lcl_sock->fd, pc_buff_ptr, u_buff_size);
#else
- u_sent_bytes = tnet_socket_send_stream(p_self->p_lcl_sock, pc_buff_ptr, u_buff_size);
+ u_sent_bytes = tnet_socket_send_stream(p_self->p_lcl_sock, pc_buff_ptr, u_buff_size);
#endif
- }
- }
+ }
+ }
}
- if (u_sent_bytes != u_buff_size) {
+ if (u_sent_bytes != u_buff_size) {
TSK_DEBUG_ERROR("Failed to send %u bytes. Only %u sent", (unsigned)u_buff_size, (unsigned)u_sent_bytes);
ret = -2;
goto bail;
@@ -1618,21 +1628,21 @@ bail:
static int _tnet_turn_session_send_buff(tnet_turn_session_t* p_self, const void* pc_buff_ptr, tsk_size_t u_buff_size)
{
- return _tnet_turn_session_send_buff_0(p_self, tsk_null/*peer*/, pc_buff_ptr, u_buff_size);
+ return _tnet_turn_session_send_buff_0(p_self, tsk_null/*peer*/, pc_buff_ptr, u_buff_size);
}
static int _tnet_turn_session_send_pkt_0(tnet_turn_session_t* p_self, const tnet_turn_peer_t* pc_peer, const tnet_turn_pkt_t *pc_pkt)
{
- int ret;
- tsk_size_t u_min_size;
- if (!p_self || !pc_pkt) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
+ int ret;
+ tsk_size_t u_min_size;
+ if (!p_self || !pc_pkt) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
- tsk_safeobj_lock(p_self);
+ tsk_safeobj_lock(p_self);
- if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_pkt, &u_min_size))) {
+ if ((ret = tnet_stun_pkt_get_size_in_octetunits_with_padding(pc_pkt, &u_min_size))) {
goto bail;
}
u_min_size += kStunBuffMinPad;
@@ -1649,32 +1659,32 @@ static int _tnet_turn_session_send_pkt_0(tnet_turn_session_t* p_self, const tnet
if ((ret = tnet_stun_pkt_write_with_padding(pc_pkt, p_self->p_buff_send_ptr, p_self->u_buff_send_size, &u_min_size))) {
goto bail;
}
- if ((ret = _tnet_turn_session_send_buff_0(p_self, pc_peer, p_self->p_buff_send_ptr, u_min_size))) {
- goto bail;
- }
+ if ((ret = _tnet_turn_session_send_buff_0(p_self, pc_peer, p_self->p_buff_send_ptr, u_min_size))) {
+ goto bail;
+ }
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
static int _tnet_turn_session_send_pkt(tnet_turn_session_t* p_self, const tnet_turn_pkt_t *pc_pkt)
{
- return _tnet_turn_session_send_pkt_0(p_self, tsk_null/*peer*/, pc_pkt);
+ return _tnet_turn_session_send_pkt_0(p_self, tsk_null/*peer*/, pc_pkt);
}
// 420 = Unknown Attribute
int _tnet_turn_session_process_err420_pkt(tnet_turn_pkt_t *p_pkt_req, const tnet_turn_pkt_t *pc_pkt_resp420)
{
- const tnet_stun_attr_vdata_t* pc_attr;
- uint16_t u16;
- int ret;
- tsk_bool_t b_done = tsk_false;
- if (!p_pkt_req || !pc_pkt_resp420) {
- TSK_DEBUG_ERROR("Invalid parameter");
+ const tnet_stun_attr_vdata_t* pc_attr;
+ uint16_t u16;
+ int ret;
+ tsk_bool_t b_done = tsk_false;
+ if (!p_pkt_req || !pc_pkt_resp420) {
+ TSK_DEBUG_ERROR("Invalid parameter");
return -1;
- }
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt_resp420, tnet_stun_attr_type_unknown_attrs, (const tnet_stun_attr_t**)&pc_attr))) {
+ }
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt_resp420, tnet_stun_attr_type_unknown_attrs, (const tnet_stun_attr_t**)&pc_attr))) {
goto bail;
}
if (!pc_attr || !pc_attr->p_data_ptr || (pc_attr->u_data_size & 1)) {
@@ -1682,288 +1692,284 @@ int _tnet_turn_session_process_err420_pkt(tnet_turn_pkt_t *p_pkt_req, const tnet
ret = -3;
goto bail;
}
- for (u16 = 0; u16 < pc_attr->u_data_size; u16+=2) {
- switch (*((uint16_t*)&pc_attr->p_data_ptr[u16])) {
- case tnet_stun_attr_type_dont_fragment:
- {
- p_pkt_req->opt.dontfrag = 0;
- b_done = tsk_true;
- break;
- }
- case tnet_stun_attr_type_fingerprint:
- {
- p_pkt_req->opt.fingerprint = 0;
- b_done = tsk_true;
- break;
- }
- }
- }
+ for (u16 = 0; u16 < pc_attr->u_data_size; u16+=2) {
+ switch (*((uint16_t*)&pc_attr->p_data_ptr[u16])) {
+ case tnet_stun_attr_type_dont_fragment: {
+ p_pkt_req->opt.dontfrag = 0;
+ b_done = tsk_true;
+ break;
+ }
+ case tnet_stun_attr_type_fingerprint: {
+ p_pkt_req->opt.fingerprint = 0;
+ b_done = tsk_true;
+ break;
+ }
+ }
+ }
- if (b_done) {
- // TRANSACTION-ID
- if ((ret = tnet_stun_utils_transac_id_rand(&p_pkt_req->transac_id))) {
- goto bail;
- }
- }
+ if (b_done) {
+ // TRANSACTION-ID
+ if ((ret = tnet_stun_utils_transac_id_rand(&p_pkt_req->transac_id))) {
+ goto bail;
+ }
+ }
bail:
- return ret;
+ return ret;
}
static int _tnet_turn_session_process_incoming_pkt(struct tnet_turn_session_s* p_self, const tnet_turn_pkt_t *pc_pkt, tsk_bool_t *pb_processed)
{
- int ret = 0;
+ int ret = 0;
if (!p_self || !pc_pkt || !pb_processed) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
- *pb_processed = tsk_false;
+ *pb_processed = tsk_false;
// lock()
tsk_safeobj_lock(p_self);
- switch (pc_pkt->e_type) {
- case tnet_stun_pkt_type_allocate_success_response:
- case tnet_stun_pkt_type_allocate_error_response:
- case tnet_stun_pkt_type_createpermission_success_response:
- case tnet_stun_pkt_type_createpermission_error_response:
- case tnet_stun_pkt_type_channelbind_success_response:
- case tnet_stun_pkt_type_channelbind_error_response:
- case tnet_stun_pkt_type_refresh_success_response:
- case tnet_stun_pkt_type_refresh_error_response:
- case tnet_stun_pkt_type_connect_success_response:
- case tnet_stun_pkt_type_connect_error_response:
- case tnet_stun_pkt_type_connectionbind_success_response:
- case tnet_stun_pkt_type_connectionbind_error_response:
- {
- const tnet_stun_attr_error_code_t* pc_attr_err = tsk_null;
- uint16_t u_code = 0;
- tnet_turn_pkt_t *pc_pkt_req = tsk_null;
- tnet_turn_peer_t* pc_peer = tsk_null;
-
+ switch (pc_pkt->e_type) {
+ case tnet_stun_pkt_type_allocate_success_response:
+ case tnet_stun_pkt_type_allocate_error_response:
+ case tnet_stun_pkt_type_createpermission_success_response:
+ case tnet_stun_pkt_type_createpermission_error_response:
+ case tnet_stun_pkt_type_channelbind_success_response:
+ case tnet_stun_pkt_type_channelbind_error_response:
+ case tnet_stun_pkt_type_refresh_success_response:
+ case tnet_stun_pkt_type_refresh_error_response:
+ case tnet_stun_pkt_type_connect_success_response:
+ case tnet_stun_pkt_type_connect_error_response:
+ case tnet_stun_pkt_type_connectionbind_success_response:
+ case tnet_stun_pkt_type_connectionbind_error_response: {
+ const tnet_stun_attr_error_code_t* pc_attr_err = tsk_null;
+ uint16_t u_code = 0;
+ tnet_turn_pkt_t *pc_pkt_req = tsk_null;
+ tnet_turn_peer_t* pc_peer = tsk_null;
+
#define CANCEL_TIMER(parent, which) \
if (TSK_TIMER_ID_IS_VALID(parent->timer.rtt.which.id)) { \
tsk_timer_manager_cancel(p_self->timer.p_mgr, parent->timer.rtt.which.id); \
parent->timer.rtt.which.id = TSK_INVALID_TIMER_ID; \
}
- // Find request
- if (p_self->p_pkt_alloc && tnet_stun_utils_transac_id_cmp(p_self->p_pkt_alloc->transac_id, pc_pkt->transac_id) == 0) {
- pc_pkt_req = p_self->p_pkt_alloc;
- CANCEL_TIMER(p_self, alloc);
- CANCEL_TIMER(p_self, refresh);
- }
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_createperm, &pc_pkt->transac_id))) {
- pc_pkt_req = pc_peer->p_pkt_createperm;
- CANCEL_TIMER(pc_peer, createperm);
- }
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_sendind, &pc_pkt->transac_id))) {
- pc_pkt_req = pc_peer->p_pkt_sendind;
- }
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_chanbind, &pc_pkt->transac_id))) {
- pc_pkt_req = pc_peer->p_pkt_chanbind;
- CANCEL_TIMER(pc_peer, chanbind);
- }
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_connect, &pc_pkt->transac_id))) {
- pc_pkt_req = pc_peer->p_pkt_connect;
- // TCP: no timer
- }
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_connectionbind, &pc_pkt->transac_id))) {
- pc_pkt_req = pc_peer->p_pkt_connbind;
- // TCP: no timer
- }
- else if (p_self->p_pkt_refresh && tnet_stun_utils_transac_id_cmp(p_self->p_pkt_refresh->transac_id, pc_pkt->transac_id) == 0) {
- pc_pkt_req = p_self->p_pkt_refresh;
- CANCEL_TIMER(p_self, refresh);
- }
-
- if (!pc_pkt_req) {
- TSK_DEBUG_INFO("No matching request[TID=%s]", pc_pkt->transac_id);
- // Not an error as the "fd" could be shared by several processes (e.g. ICE)
- goto bail;
- }
-
- /*** SUCCESS ***/
- if (TNET_STUN_PKT_RESP_IS_SUCCESS(pc_pkt)) {
- // --- ALLOC --- //
- if (pc_pkt_req == p_self->p_pkt_alloc) {
- const tnet_stun_attr_address_t *pc_attr_addr;
- tnet_ip_t ip_addr;
- const tnet_stun_attr_vdata_t *pc_attr_lifetime;
- // XOR-MAPPED-ADDRESS (optional)
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_attr_addr)) == 0 && pc_attr_addr) {
- if ((ret = tnet_stun_utils_inet_ntop((pc_attr_addr->e_family == tnet_stun_address_family_ipv6), &pc_attr_addr->address, &ip_addr)) == 0) {
- p_self->b_srflx_ipv6 = (pc_attr_addr->e_family == tnet_stun_address_family_ipv6);
- p_self->u_srflx_port = pc_attr_addr->u_port;
- tsk_strupdate(&p_self->p_srflx_ip, ip_addr);
- }
- }
- // LIFETIME (optional)
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_lifetime, (const tnet_stun_attr_t**)&pc_attr_lifetime)) == 0 && pc_attr_lifetime && pc_attr_lifetime->u_data_size == 4) {
- p_self->u_lifetime_alloc_in_sec = TSK_TO_UINT32(pc_attr_lifetime->p_data_ptr);
- }
- // XOR-RELAYED-ADDRESS (required)
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_xor_relayed_address, (const tnet_stun_attr_t**)&pc_attr_addr))) {
- _tnet_turn_session_raise_event_alloc_nok(p_self);
- goto bail;
- }
- if (!pc_attr_addr) {
- TSK_DEBUG_ERROR("XOR-RELAYED-ADDRESS missing in success response for Allocate");
- ret = -4;
- _tnet_turn_session_raise_event_alloc_nok(p_self);
- goto bail;
- }
- if ((ret = tnet_stun_utils_inet_ntop((pc_attr_addr->e_family == tnet_stun_address_family_ipv6), &pc_attr_addr->address, &ip_addr))) {
- _tnet_turn_session_raise_event_alloc_nok(p_self);
- goto bail;
- }
-
- // Uncomment to test [TURN Client] <-> [Turn Server] <-> [Any Client]
+ // Find request
+ if (p_self->p_pkt_alloc && tnet_stun_utils_transac_id_cmp(p_self->p_pkt_alloc->transac_id, pc_pkt->transac_id) == 0) {
+ pc_pkt_req = p_self->p_pkt_alloc;
+ CANCEL_TIMER(p_self, alloc);
+ CANCEL_TIMER(p_self, refresh);
+ }
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_createperm, &pc_pkt->transac_id))) {
+ pc_pkt_req = pc_peer->p_pkt_createperm;
+ CANCEL_TIMER(pc_peer, createperm);
+ }
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_sendind, &pc_pkt->transac_id))) {
+ pc_pkt_req = pc_peer->p_pkt_sendind;
+ }
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_chanbind, &pc_pkt->transac_id))) {
+ pc_pkt_req = pc_peer->p_pkt_chanbind;
+ CANCEL_TIMER(pc_peer, chanbind);
+ }
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_connect, &pc_pkt->transac_id))) {
+ pc_pkt_req = pc_peer->p_pkt_connect;
+ // TCP: no timer
+ }
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_self->p_list_peers, __pred_find_peer_by_transacid_connectionbind, &pc_pkt->transac_id))) {
+ pc_pkt_req = pc_peer->p_pkt_connbind;
+ // TCP: no timer
+ }
+ else if (p_self->p_pkt_refresh && tnet_stun_utils_transac_id_cmp(p_self->p_pkt_refresh->transac_id, pc_pkt->transac_id) == 0) {
+ pc_pkt_req = p_self->p_pkt_refresh;
+ CANCEL_TIMER(p_self, refresh);
+ }
+
+ if (!pc_pkt_req) {
+ TSK_DEBUG_INFO("No matching request[TID=%s]", pc_pkt->transac_id);
+ // Not an error as the "fd" could be shared by several processes (e.g. ICE)
+ goto bail;
+ }
+
+ /*** SUCCESS ***/
+ if (TNET_STUN_PKT_RESP_IS_SUCCESS(pc_pkt)) {
+ // --- ALLOC --- //
+ if (pc_pkt_req == p_self->p_pkt_alloc) {
+ const tnet_stun_attr_address_t *pc_attr_addr;
+ tnet_ip_t ip_addr;
+ const tnet_stun_attr_vdata_t *pc_attr_lifetime;
+ // XOR-MAPPED-ADDRESS (optional)
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_xor_mapped_address, (const tnet_stun_attr_t**)&pc_attr_addr)) == 0 && pc_attr_addr) {
+ if ((ret = tnet_stun_utils_inet_ntop((pc_attr_addr->e_family == tnet_stun_address_family_ipv6), &pc_attr_addr->address, &ip_addr)) == 0) {
+ p_self->b_srflx_ipv6 = (pc_attr_addr->e_family == tnet_stun_address_family_ipv6);
+ p_self->u_srflx_port = pc_attr_addr->u_port;
+ tsk_strupdate(&p_self->p_srflx_ip, ip_addr);
+ }
+ }
+ // LIFETIME (optional)
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_lifetime, (const tnet_stun_attr_t**)&pc_attr_lifetime)) == 0 && pc_attr_lifetime && pc_attr_lifetime->u_data_size == 4) {
+ p_self->u_lifetime_alloc_in_sec = TSK_TO_UINT32(pc_attr_lifetime->p_data_ptr);
+ }
+ // XOR-RELAYED-ADDRESS (required)
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_xor_relayed_address, (const tnet_stun_attr_t**)&pc_attr_addr))) {
+ _tnet_turn_session_raise_event_alloc_nok(p_self);
+ goto bail;
+ }
+ if (!pc_attr_addr) {
+ TSK_DEBUG_ERROR("XOR-RELAYED-ADDRESS missing in success response for Allocate");
+ ret = -4;
+ _tnet_turn_session_raise_event_alloc_nok(p_self);
+ goto bail;
+ }
+ if ((ret = tnet_stun_utils_inet_ntop((pc_attr_addr->e_family == tnet_stun_address_family_ipv6), &pc_attr_addr->address, &ip_addr))) {
+ _tnet_turn_session_raise_event_alloc_nok(p_self);
+ goto bail;
+ }
+
+ // Uncomment to test [TURN Client] <-> [Turn Server] <-> [Any Client]
#if 0
- {
- struct sockaddr_storage to;
- tnet_sockaddr_init(ip_addr, pc_attr_addr->u_port, p_self->p_lcl_sock->type, &to);
- tnet_sockfd_sendto(p_self->p_lcl_sock->fd, (const struct sockaddr*)&to, "pinhole", 7); // open pinhole to allow incoming data
- tnet_sockfd_sendto(p_self->p_lcl_sock->fd, (const struct sockaddr*)&to, "pinhole", 7); // open pinhole to allow incoming data
- }
+ {
+ struct sockaddr_storage to;
+ tnet_sockaddr_init(ip_addr, pc_attr_addr->u_port, p_self->p_lcl_sock->type, &to);
+ tnet_sockfd_sendto(p_self->p_lcl_sock->fd, (const struct sockaddr*)&to, "pinhole", 7); // open pinhole to allow incoming data
+ tnet_sockfd_sendto(p_self->p_lcl_sock->fd, (const struct sockaddr*)&to, "pinhole", 7); // open pinhole to allow incoming data
+ }
#endif
- // Schedule refresh
- TNET_TURN_SESSION_TIMER_SCHEDULE_SEC(p_self, p_self->timer.u_timer_id_refresh, p_self->u_lifetime_alloc_in_sec);
-
- p_self->e_alloc_state = tnet_stun_state_ok;
- p_self->b_rel_ipv6 = (pc_attr_addr->e_family == tnet_stun_address_family_ipv6);
- p_self->u_rel_port = pc_attr_addr->u_port;
- tsk_strupdate(&p_self->p_rel_ip, ip_addr);
-
- _tnet_turn_session_raise_event_alloc_ok(p_self);
- }
- // --- CREATE-PERMISSION --- //
- else if (pc_pkt_req->e_type == tnet_stun_pkt_type_createpermission_request) {
- TSK_DEBUG_INFO("TURN 'CREATE-PERMISSION' OK for peer-id = %ld", pc_peer->id);
- pc_peer->e_createperm_state = tnet_stun_state_ok;
- TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, pc_peer->timer.fresh.createperm.id, pc_peer->timer.fresh.createperm.u_timeout);
- _tnet_turn_session_raise_event_createperm_ok(p_self, pc_peer->id);
- }
- // --- CHANNEL-BIND --- //
- else if (pc_pkt_req->e_type == tnet_stun_pkt_type_channelbind_request) {
- TSK_DEBUG_INFO("TURN 'CHANNEL-BIND' OK for peer-id = %ld", pc_peer->id);
- pc_peer->e_chanbind_state = tnet_stun_state_ok;
- TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, pc_peer->timer.fresh.chanbind.id, pc_peer->timer.fresh.chanbind.u_timeout);
- _tnet_turn_session_raise_event_chanbind_ok(p_self, pc_peer->id);
- }
- // --- CONNECT --- //
- else if (pc_pkt_req->e_type == tnet_stun_pkt_type_connect_request) {
- TSK_DEBUG_INFO("TURN 'CONNECT' OK for peer-id = %ld", pc_peer->id);
- if ((ret = _tnet_turn_session_process_success_connect_pkt(p_self, pc_peer, pc_pkt))) {
- goto bail;
- }
- }
- // --- CONNECTION-BIND --- //
- else if (pc_pkt_req->e_type == tnet_stun_pkt_type_connectionbind_request) {
- TSK_DEBUG_INFO("TURN 'CONNECTION-BIND' OK for peer-id = %ld", pc_peer->id);
- pc_peer->e_connbind_state = tnet_stun_state_ok;
- _tnet_turn_session_raise_event_connectionbind_ok(p_self, pc_peer->id);
- }
- // --- REFRESH --- //
- else if (pc_pkt_req == p_self->p_pkt_refresh) {
- const tnet_stun_attr_vdata_t *pc_attr_lifetime;
- TSK_DEBUG_INFO("TURN 'REFRESH' OK for peer-id = %ld", pc_peer ? pc_peer->id : -1);
- p_self->e_refresh_state = tnet_stun_state_ok;
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_lifetime, (const tnet_stun_attr_t**)&pc_attr_lifetime)) == 0 && pc_attr_lifetime && pc_attr_lifetime->u_data_size == 4) {
- p_self->u_lifetime_alloc_in_sec = TSK_TO_UINT32(pc_attr_lifetime->p_data_ptr);
- }
- TNET_TURN_SESSION_TIMER_SCHEDULE_SEC(p_self, p_self->timer.u_timer_id_refresh, p_self->u_lifetime_alloc_in_sec);
- _tnet_turn_session_raise_event_refresh_ok(p_self);
- }
- }
- /*** ERROR ***/
- else {
- tsk_bool_t b_nok = tsk_true;
- if ((ret = tnet_stun_pkt_get_errorcode(pc_pkt, &u_code))) {
- goto bail;
- }
- if (u_code > 299) {
- tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_error_code, (const tnet_stun_attr_t**)&pc_attr_err);
- }
- if (u_code == kStunErrCodeUnauthorized || u_code == kStunErrCodeStaleNonce) {
- if (u_code == kStunErrCodeUnauthorized) {
- // Make sure this is not an authentication failure (#2 401)
- // Do not send another req to avoid endless messages
- if ((tnet_stun_pkt_attr_exists(pc_pkt_req, tnet_stun_attr_type_message_integrity))) { // already has a MESSAGE-INTEGRITY?
- TSK_DEBUG_ERROR("TURN authentication failed");
- goto check_nok;
- // INDICATION messages cannot receive 401 responses
- }
- }
- if ((ret = tnet_stun_pkt_auth_prepare_2(pc_pkt_req, p_self->cred.p_usr_name, p_self->cred.p_pwd, pc_pkt))) {
- goto check_nok;
- }
- if ((ret = _tnet_turn_session_send_pkt_0(p_self, pc_peer, pc_pkt_req)) == 0) {
- b_nok = tsk_false; goto check_nok;
- }
- }
- else if (u_code == kStunErrCodeUnknownAttributes) {
- if((ret = _tnet_turn_session_process_err420_pkt(pc_pkt_req, pc_pkt))) {
- goto check_nok;
- }
- if ((ret = _tnet_turn_session_send_pkt_0(p_self, pc_peer, pc_pkt_req)) == 0) {
- b_nok = tsk_false; goto check_nok;
- }
- }
+ // Schedule refresh
+ TNET_TURN_SESSION_TIMER_SCHEDULE_SEC(p_self, p_self->timer.u_timer_id_refresh, p_self->u_lifetime_alloc_in_sec);
+
+ p_self->e_alloc_state = tnet_stun_state_ok;
+ p_self->b_rel_ipv6 = (pc_attr_addr->e_family == tnet_stun_address_family_ipv6);
+ p_self->u_rel_port = pc_attr_addr->u_port;
+ tsk_strupdate(&p_self->p_rel_ip, ip_addr);
+
+ _tnet_turn_session_raise_event_alloc_ok(p_self);
+ }
+ // --- CREATE-PERMISSION --- //
+ else if (pc_pkt_req->e_type == tnet_stun_pkt_type_createpermission_request) {
+ TSK_DEBUG_INFO("TURN 'CREATE-PERMISSION' OK for peer-id = %ld", pc_peer->id);
+ pc_peer->e_createperm_state = tnet_stun_state_ok;
+ TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, pc_peer->timer.fresh.createperm.id, pc_peer->timer.fresh.createperm.u_timeout);
+ _tnet_turn_session_raise_event_createperm_ok(p_self, pc_peer->id);
+ }
+ // --- CHANNEL-BIND --- //
+ else if (pc_pkt_req->e_type == tnet_stun_pkt_type_channelbind_request) {
+ TSK_DEBUG_INFO("TURN 'CHANNEL-BIND' OK for peer-id = %ld", pc_peer->id);
+ pc_peer->e_chanbind_state = tnet_stun_state_ok;
+ TNET_TURN_SESSION_TIMER_SCHEDULE_MILLIS(p_self, pc_peer->timer.fresh.chanbind.id, pc_peer->timer.fresh.chanbind.u_timeout);
+ _tnet_turn_session_raise_event_chanbind_ok(p_self, pc_peer->id);
+ }
+ // --- CONNECT --- //
+ else if (pc_pkt_req->e_type == tnet_stun_pkt_type_connect_request) {
+ TSK_DEBUG_INFO("TURN 'CONNECT' OK for peer-id = %ld", pc_peer->id);
+ if ((ret = _tnet_turn_session_process_success_connect_pkt(p_self, pc_peer, pc_pkt))) {
+ goto bail;
+ }
+ }
+ // --- CONNECTION-BIND --- //
+ else if (pc_pkt_req->e_type == tnet_stun_pkt_type_connectionbind_request) {
+ TSK_DEBUG_INFO("TURN 'CONNECTION-BIND' OK for peer-id = %ld", pc_peer->id);
+ pc_peer->e_connbind_state = tnet_stun_state_ok;
+ _tnet_turn_session_raise_event_connectionbind_ok(p_self, pc_peer->id);
+ }
+ // --- REFRESH --- //
+ else if (pc_pkt_req == p_self->p_pkt_refresh) {
+ const tnet_stun_attr_vdata_t *pc_attr_lifetime;
+ TSK_DEBUG_INFO("TURN 'REFRESH' OK for peer-id = %ld", pc_peer ? pc_peer->id : -1);
+ p_self->e_refresh_state = tnet_stun_state_ok;
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_lifetime, (const tnet_stun_attr_t**)&pc_attr_lifetime)) == 0 && pc_attr_lifetime && pc_attr_lifetime->u_data_size == 4) {
+ p_self->u_lifetime_alloc_in_sec = TSK_TO_UINT32(pc_attr_lifetime->p_data_ptr);
+ }
+ TNET_TURN_SESSION_TIMER_SCHEDULE_SEC(p_self, p_self->timer.u_timer_id_refresh, p_self->u_lifetime_alloc_in_sec);
+ _tnet_turn_session_raise_event_refresh_ok(p_self);
+ }
+ }
+ /*** ERROR ***/
+ else {
+ tsk_bool_t b_nok = tsk_true;
+ if ((ret = tnet_stun_pkt_get_errorcode(pc_pkt, &u_code))) {
+ goto bail;
+ }
+ if (u_code > 299) {
+ tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_error_code, (const tnet_stun_attr_t**)&pc_attr_err);
+ }
+ if (u_code == kStunErrCodeUnauthorized || u_code == kStunErrCodeStaleNonce) {
+ if (u_code == kStunErrCodeUnauthorized) {
+ // Make sure this is not an authentication failure (#2 401)
+ // Do not send another req to avoid endless messages
+ if ((tnet_stun_pkt_attr_exists(pc_pkt_req, tnet_stun_attr_type_message_integrity))) { // already has a MESSAGE-INTEGRITY?
+ TSK_DEBUG_ERROR("TURN authentication failed");
+ goto check_nok;
+ // INDICATION messages cannot receive 401 responses
+ }
+ }
+ if ((ret = tnet_stun_pkt_auth_prepare_2(pc_pkt_req, p_self->cred.p_usr_name, p_self->cred.p_pwd, pc_pkt))) {
+ goto check_nok;
+ }
+ if ((ret = _tnet_turn_session_send_pkt_0(p_self, pc_peer, pc_pkt_req)) == 0) {
+ b_nok = tsk_false;
+ goto check_nok;
+ }
+ }
+ else if (u_code == kStunErrCodeUnknownAttributes) {
+ if((ret = _tnet_turn_session_process_err420_pkt(pc_pkt_req, pc_pkt))) {
+ goto check_nok;
+ }
+ if ((ret = _tnet_turn_session_send_pkt_0(p_self, pc_peer, pc_pkt_req)) == 0) {
+ b_nok = tsk_false;
+ goto check_nok;
+ }
+ }
check_nok:
- if (b_nok) {
- TSK_DEBUG_INFO("--- TURN response code = %hu, phrase = %s, peer-id=%ld, ---",
- u_code, pc_attr_err ? pc_attr_err->p_reason_phrase : "null", pc_peer ? pc_peer->id : -1);
- if (pc_pkt_req == p_self->p_pkt_alloc) {
- p_self->e_alloc_state = tnet_stun_state_nok;
- _tnet_turn_session_raise_event_alloc_nok(p_self);
- }
- else if (pc_pkt_req->e_type == tnet_stun_pkt_type_channelbind_request) {
- pc_peer->e_chanbind_state = tnet_stun_state_nok;
- _tnet_turn_session_raise_event_chanbind_nok(p_self, pc_peer->id);
- }
- else if (pc_pkt_req->e_type == tnet_stun_pkt_type_createpermission_request) {
- pc_peer->e_createperm_state = tnet_stun_state_nok;
- _tnet_turn_session_raise_event_createperm_nok(p_self, pc_peer->id);
- }
- else if (pc_pkt_req == p_self->p_pkt_refresh) {
- p_self->e_refresh_state = tnet_stun_state_nok;
- _tnet_turn_session_raise_event_refresh_nok(p_self);
- }
- }
- }
-
- break;
- }
- case tnet_stun_pkt_type_connectionattempt_indication:
- {
- // Indicates we already have an active connection
- const tnet_stun_attr_address_t *pc_attr_xor_peer_addr;
- tnet_turn_peer_t* pc_peer = tsk_null;
- // XOR-PEER-ADDRESS
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_xor_peer_address, (const tnet_stun_attr_t**)&pc_attr_xor_peer_addr)) == 0 && pc_attr_xor_peer_addr) {
- if ((ret = _tnet_turn_peer_find_by_xpeer(p_self->p_list_peers, pc_attr_xor_peer_addr, (const tnet_turn_peer_t**)&pc_peer)) == 0 && pc_peer) {
- if ((ret = _tnet_turn_session_process_success_connect_pkt(p_self, pc_peer, pc_pkt))) {
- goto bail;
- }
- }
- }
- break;
- }
- case tnet_stun_pkt_type_data_indication:
- {
- TSK_DEBUG_ERROR("Unexpected code called"); // --> DATA-INDICATION must be handled in net-event
- break;
- }
- default:
- {
- goto bail;
- }
- }
+ if (b_nok) {
+ TSK_DEBUG_INFO("--- TURN response code = %hu, phrase = %s, peer-id=%ld, ---",
+ u_code, pc_attr_err ? pc_attr_err->p_reason_phrase : "null", pc_peer ? pc_peer->id : -1);
+ if (pc_pkt_req == p_self->p_pkt_alloc) {
+ p_self->e_alloc_state = tnet_stun_state_nok;
+ _tnet_turn_session_raise_event_alloc_nok(p_self);
+ }
+ else if (pc_pkt_req->e_type == tnet_stun_pkt_type_channelbind_request) {
+ pc_peer->e_chanbind_state = tnet_stun_state_nok;
+ _tnet_turn_session_raise_event_chanbind_nok(p_self, pc_peer->id);
+ }
+ else if (pc_pkt_req->e_type == tnet_stun_pkt_type_createpermission_request) {
+ pc_peer->e_createperm_state = tnet_stun_state_nok;
+ _tnet_turn_session_raise_event_createperm_nok(p_self, pc_peer->id);
+ }
+ else if (pc_pkt_req == p_self->p_pkt_refresh) {
+ p_self->e_refresh_state = tnet_stun_state_nok;
+ _tnet_turn_session_raise_event_refresh_nok(p_self);
+ }
+ }
+ }
- *pb_processed = tsk_true;
+ break;
+ }
+ case tnet_stun_pkt_type_connectionattempt_indication: {
+ // Indicates we already have an active connection
+ const tnet_stun_attr_address_t *pc_attr_xor_peer_addr;
+ tnet_turn_peer_t* pc_peer = tsk_null;
+ // XOR-PEER-ADDRESS
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_xor_peer_address, (const tnet_stun_attr_t**)&pc_attr_xor_peer_addr)) == 0 && pc_attr_xor_peer_addr) {
+ if ((ret = _tnet_turn_peer_find_by_xpeer(p_self->p_list_peers, pc_attr_xor_peer_addr, (const tnet_turn_peer_t**)&pc_peer)) == 0 && pc_peer) {
+ if ((ret = _tnet_turn_session_process_success_connect_pkt(p_self, pc_peer, pc_pkt))) {
+ goto bail;
+ }
+ }
+ }
+ break;
+ }
+ case tnet_stun_pkt_type_data_indication: {
+ TSK_DEBUG_ERROR("Unexpected code called"); // --> DATA-INDICATION must be handled in net-event
+ break;
+ }
+ default: {
+ goto bail;
+ }
+ }
+
+ *pb_processed = tsk_true;
bail:
// unlock()
@@ -1974,38 +1980,38 @@ bail:
// "pc_pkt" could be "200 response" or "CONNECTATTEMP-INDICATION"
int _tnet_turn_session_process_success_connect_pkt(struct tnet_turn_session_s* p_self, tnet_turn_peer_t* pc_peer, const tnet_turn_pkt_t *pc_pkt)
{
- int ret = 0;
- const tnet_stun_attr_vdata_t *pc_attr_connection_id;
+ int ret = 0;
+ const tnet_stun_attr_vdata_t *pc_attr_connection_id;
if (!p_self || !pc_peer || !pc_pkt) {
TSK_DEBUG_ERROR("Invalid parameter");
return -1;
}
- if (pc_pkt->e_type != tnet_stun_pkt_type_connectionattempt_indication && !TNET_STUN_PKT_RESP_IS_SUCCESS(pc_pkt)) {
- TSK_DEBUG_ERROR("Invalid packet type");
- ret = -2;
- goto bail;
- }
-
+ if (pc_pkt->e_type != tnet_stun_pkt_type_connectionattempt_indication && !TNET_STUN_PKT_RESP_IS_SUCCESS(pc_pkt)) {
+ TSK_DEBUG_ERROR("Invalid packet type");
+ ret = -2;
+ goto bail;
+ }
+
// lock()
tsk_safeobj_lock(p_self);
-
- if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_connection_id, (const tnet_stun_attr_t**)&pc_attr_connection_id)) == 0 && pc_attr_connection_id && pc_attr_connection_id->u_data_size == 4) {
- pc_peer->u_conn_id = TSK_TO_UINT32(pc_attr_connection_id->p_data_ptr);
- pc_peer->e_connect_state = tnet_stun_state_ok;
- _tnet_turn_session_raise_event_connect_ok(p_self, pc_peer->id);
- // Connect to the server and send "ConnectionBind" request using the "CONNECTION-ID" once connection is completed
- pc_peer->conn_fd = tnet_transport_connectto(p_self->p_transport, p_self->p_srv_host, p_self->u_srv_port, p_self->p_transport->type);
- if (pc_peer->conn_fd == TNET_INVALID_FD) {
- TSK_DEBUG_ERROR("Failed to connect to %s:%d", p_self->p_srv_host, p_self->u_srv_port);
- ret = -3;
- goto bail;
- }
- }
+
+ if ((ret = tnet_stun_pkt_attr_find_first(pc_pkt, tnet_stun_attr_type_connection_id, (const tnet_stun_attr_t**)&pc_attr_connection_id)) == 0 && pc_attr_connection_id && pc_attr_connection_id->u_data_size == 4) {
+ pc_peer->u_conn_id = TSK_TO_UINT32(pc_attr_connection_id->p_data_ptr);
+ pc_peer->e_connect_state = tnet_stun_state_ok;
+ _tnet_turn_session_raise_event_connect_ok(p_self, pc_peer->id);
+ // Connect to the server and send "ConnectionBind" request using the "CONNECTION-ID" once connection is completed
+ pc_peer->conn_fd = tnet_transport_connectto(p_self->p_transport, p_self->p_srv_host, p_self->u_srv_port, p_self->p_transport->type);
+ if (pc_peer->conn_fd == TNET_INVALID_FD) {
+ TSK_DEBUG_ERROR("Failed to connect to %s:%d", p_self->p_srv_host, p_self->u_srv_port);
+ ret = -3;
+ goto bail;
+ }
+ }
bail:
- tsk_safeobj_unlock(p_self);
- return ret;
+ tsk_safeobj_unlock(p_self);
+ return ret;
}
static int _tnet_turn_session_transport_layer_dgram_cb(const tnet_transport_event_t* e)
@@ -2015,252 +2021,252 @@ static int _tnet_turn_session_transport_layer_dgram_cb(const tnet_transport_even
static int _tnet_turn_session_transport_layer_stream_cb(const tnet_transport_event_t* e)
{
- return _tnet_turn_session_transport_layer_process_cb(e);
+ return _tnet_turn_session_transport_layer_process_cb(e);
}
static int _tnet_turn_session_transport_layer_process_cb(const tnet_transport_event_t* e)
{
- tnet_turn_session_t* p_ss = (tnet_turn_session_t*)e->callback_data;
- int ret = 0;
- tnet_turn_pkt_t* p_pkt = tsk_null;
- tsk_buffer_t* p_stream_buff_in = tsk_null;
- const void* pc_data = tsk_null;
- tsk_size_t u_data_size = 0;
- tsk_bool_t b_stream = tsk_false, b_stream_appended = tsk_false, b_pkt_is_complete = tsk_false, b_got_msg= tsk_false;
- tnet_turn_peer_t* pc_peer = tsk_null;
- switch(e->type){
- case event_data:
- break;
- case event_brokenpipe:
- tsk_safeobj_lock(p_ss);
- if (p_ss->p_lcl_sock && e->local_fd == p_ss->p_lcl_sock->fd) {
- tnet_fd_t broken_fd = e->local_fd;
- tsk_bool_t registered_fd = !!tnet_transport_have_socket(p_ss->p_transport, broken_fd);
+ tnet_turn_session_t* p_ss = (tnet_turn_session_t*)e->callback_data;
+ int ret = 0;
+ tnet_turn_pkt_t* p_pkt = tsk_null;
+ tsk_buffer_t* p_stream_buff_in = tsk_null;
+ const void* pc_data = tsk_null;
+ tsk_size_t u_data_size = 0;
+ tsk_bool_t b_stream = tsk_false, b_stream_appended = tsk_false, b_pkt_is_complete = tsk_false, b_got_msg= tsk_false;
+ tnet_turn_peer_t* pc_peer = tsk_null;
+ switch(e->type) {
+ case event_data:
+ break;
+ case event_brokenpipe:
+ tsk_safeobj_lock(p_ss);
+ if (p_ss->p_lcl_sock && e->local_fd == p_ss->p_lcl_sock->fd) {
+ tnet_fd_t broken_fd = e->local_fd;
+ tsk_bool_t registered_fd = !!tnet_transport_have_socket(p_ss->p_transport, broken_fd);
+ if (registered_fd) {
+ tnet_transport_remove_socket(p_ss->p_transport, &broken_fd);
+ }
+ if (tnet_socket_handle_brokenpipe(p_ss->p_lcl_sock) == 0) {
if (registered_fd) {
- tnet_transport_remove_socket(p_ss->p_transport, &broken_fd);
- }
- if (tnet_socket_handle_brokenpipe(p_ss->p_lcl_sock) == 0) {
- if (registered_fd) {
- tnet_transport_add_socket(p_ss->p_transport, p_ss->p_lcl_sock->fd, p_ss->p_lcl_sock->type, tsk_false/* do not take ownership */, tsk_true/* only Meaningful for tls*/, tsk_null);
- }
+ tnet_transport_add_socket(p_ss->p_transport, p_ss->p_lcl_sock->fd, p_ss->p_lcl_sock->type, tsk_false/* do not take ownership */, tsk_true/* only Meaningful for tls*/, tsk_null);
}
}
+ }
+ tsk_safeobj_unlock(p_ss);
+ return 0;
+ case event_connected:
+ if (p_ss->p_lcl_sock && p_ss->p_lcl_sock->fd == e->local_fd) {
+ tsk_safeobj_lock(p_ss);
+ p_ss->b_stream_connected = tsk_true;
+ if (p_ss->p_stream_buff_out && p_ss->p_stream_buff_out->size > 0) {
+ TSK_DEBUG_INFO("Sending %u TURN pending bytes", (unsigned)p_ss->p_stream_buff_out->size);
+ _tnet_turn_session_send_buff(p_ss, p_ss->p_stream_buff_out->data, (uint16_t)p_ss->p_stream_buff_out->size);
+ TSK_OBJECT_SAFE_FREE(p_ss->p_stream_buff_out);
+ }
tsk_safeobj_unlock(p_ss);
- return 0;
- case event_connected:
- if (p_ss->p_lcl_sock && p_ss->p_lcl_sock->fd == e->local_fd) {
- tsk_safeobj_lock(p_ss);
- p_ss->b_stream_connected = tsk_true;
- if (p_ss->p_stream_buff_out && p_ss->p_stream_buff_out->size > 0) {
- TSK_DEBUG_INFO("Sending %u TURN pending bytes", (unsigned)p_ss->p_stream_buff_out->size);
- _tnet_turn_session_send_buff(p_ss, p_ss->p_stream_buff_out->data, (uint16_t)p_ss->p_stream_buff_out->size);
- TSK_OBJECT_SAFE_FREE(p_ss->p_stream_buff_out);
+ }
+ else {
+ tsk_safeobj_lock(p_ss);
+ pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
+ if (pc_peer) {
+ pc_peer->b_stream_connected = tsk_true;
+ // Send ConnectionBind
+ if ((ret = _tnet_turn_session_send_connbind(p_ss, pc_peer))) {
+ goto bail;
}
- tsk_safeobj_unlock(p_ss);
- }
- else {
- tsk_safeobj_lock(p_ss);
- pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
- if (pc_peer) {
- pc_peer->b_stream_connected = tsk_true;
- // Send ConnectionBind
- if ((ret = _tnet_turn_session_send_connbind(p_ss, pc_peer))) {
- goto bail;
- }
- }
- tsk_safeobj_unlock(p_ss);
- }
- return 0;
- case event_error:
- case event_closed:
- case event_removed:
- /* case event_removed: */
- if (p_ss->p_lcl_sock && p_ss->p_lcl_sock->fd == e->local_fd) {
- tsk_safeobj_lock(p_ss);
- p_ss->b_stream_connected = tsk_false;
- p_ss->b_stream_error = (e->type == event_error);
- TSK_OBJECT_SAFE_FREE(p_ss->p_stream_buff_out);
- tsk_safeobj_unlock(p_ss);
- }
- else {
- tsk_safeobj_lock(p_ss);
- pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
- if (pc_peer) {
- pc_peer->b_stream_connected = tsk_false;
- pc_peer->conn_fd = TNET_INVALID_FD;
- }
- tsk_safeobj_unlock(p_ss);
- }
- return 0;
- default:
- return 0;
- }
+ }
+ tsk_safeobj_unlock(p_ss);
+ }
+ return 0;
+ case event_error:
+ case event_closed:
+ case event_removed:
+ /* case event_removed: */
+ if (p_ss->p_lcl_sock && p_ss->p_lcl_sock->fd == e->local_fd) {
+ tsk_safeobj_lock(p_ss);
+ p_ss->b_stream_connected = tsk_false;
+ p_ss->b_stream_error = (e->type == event_error);
+ TSK_OBJECT_SAFE_FREE(p_ss->p_stream_buff_out);
+ tsk_safeobj_unlock(p_ss);
+ }
+ else {
+ tsk_safeobj_lock(p_ss);
+ pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
+ if (pc_peer) {
+ pc_peer->b_stream_connected = tsk_false;
+ pc_peer->conn_fd = TNET_INVALID_FD;
+ }
+ tsk_safeobj_unlock(p_ss);
+ }
+ return 0;
+ default:
+ return 0;
+ }
- /*** If the code reach this line it means we have to deal with a "NET-DATA-EVENT" ***/
+ /*** If the code reach this line it means we have to deal with a "NET-DATA-EVENT" ***/
- p_ss->cb.e.pc_enet = e;
- pc_data = e->data;
- u_data_size = e->size;
- b_stream = TNET_SOCKET_TYPE_IS_STREAM(p_ss->p_lcl_sock->type);
- b_stream_appended = tsk_false;
+ p_ss->cb.e.pc_enet = e;
+ pc_data = e->data;
+ u_data_size = e->size;
+ b_stream = TNET_SOCKET_TYPE_IS_STREAM(p_ss->p_lcl_sock->type);
+ b_stream_appended = tsk_false;
handle_data:
- b_got_msg = tsk_false;
-
- // TODO: /!\
- // - When the requested transport is TCP/TLS then we will receive RAW data on the connected peer socket which means no way to guess the end-of-the message
- // - No issue for when requested transport is UDP because we'll always have the data encapsulated in CHANNEL-DATA or DATA-INDICATION.
- if (b_stream) {
- if (!b_stream_appended) {
- tsk_safeobj_lock(p_ss);
- pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
- if (pc_peer) {
- p_stream_buff_in = tsk_object_ref(pc_peer->p_stream_buff_in);
- }
- else {
- p_stream_buff_in = tsk_object_ref(p_ss->p_stream_buff_in);
- }
- tsk_safeobj_unlock(p_ss);
-
- if ((ret = tsk_buffer_append(p_stream_buff_in, e->data, e->size))) {
- goto bail;
- }
- b_stream_appended = tsk_true;
- }
- // Guard
- if (p_stream_buff_in->size > kTurnStreamChunckMaxSize) {
- TSK_DEBUG_ERROR("Too much data in the stream buffer: %u", (unsigned)p_stream_buff_in->size);
- tsk_buffer_cleanup(p_stream_buff_in);
- goto bail;
- }
- pc_data = p_stream_buff_in->data;
- u_data_size = p_stream_buff_in->size;
- }
+ b_got_msg = tsk_false;
- if (!TNET_STUN_BUFF_IS_STUN2(((const uint8_t*)pc_data), u_data_size)) {
- // ChannelData ?
- if (TNET_STUN_BUFF_IS_CHANNEL_DATA(((const uint8_t*)pc_data), u_data_size)) {
- const uint8_t* _p_data = (const uint8_t*)pc_data;
- // Channel Number in [0x4000 - 0x7FFF]
- // rfc5766 - 11.6. Receiving a ChannelData Message
- // rfc5766 - 11.4. The ChannelData Message
- // If the message uses a value in the reserved range (0x8000 through 0xFFFF), then the message is silently discarded
- static const tsk_size_t kChannelDataHdrSize = 4; // Channel Number(2 bytes) + Length (2 bytes)
- uint16_t u_chan_num = tnet_ntohs_2(&_p_data[0]);
- if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_channum, &u_chan_num))) {
- uint16_t u_len = tnet_ntohs_2(&_p_data[2]);
- if (u_len <= (u_data_size - kChannelDataHdrSize)) {
- b_got_msg = tsk_true;
- _tnet_turn_session_raise_event_recv_data(p_ss, pc_peer->id, &_p_data[kChannelDataHdrSize], u_len);
- if (p_stream_buff_in) {
- /* The padding is not reflected in the length
- field of the ChannelData message, so the actual size of a ChannelData
- message (including padding) is (4 + Length) rounded up to the nearest
- multiple of 4. Over UDP, the padding is not required but MAY be
- included.
- */
- tsk_size_t u_pad_len = (u_len & 3) ? (4 - (u_len & 3)) : 0;
- tsk_buffer_remove(p_stream_buff_in, 0, kChannelDataHdrSize + u_len + u_pad_len);
- }
- }
- else {
- TSK_DEBUG_INFO("TURN channel data too short");
- }
- }
- goto bail;
- } // if (TNET_STUN_BUFF_IS_CHANNEL_DATA...
-
- // Must never happen: Data must be received via CHANNEL-DATA or DATA-INDICATION
- TSK_DEBUG_INFO("Calling unexpected code :(");
-
- if (b_stream) {
- tsk_safeobj_lock(p_ss);
- pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
- tsk_safeobj_unlock(p_ss);
- }
- _tnet_turn_session_raise_event_recv_data(p_ss, pc_peer ? pc_peer->id : kTurnPeerIdInvalid, pc_data, u_data_size);
- if (p_stream_buff_in) {
- tsk_buffer_cleanup(p_stream_buff_in);
- }
- goto bail;
- } // if (!TNET_STUN_BUFF_IS_STUN2...
-
- /*** At this step it means we have a STUN packet in the buffer ***/
-
- // Make sure we have a complete packet in the buffer
- if (b_stream) {
- if ((ret = tnet_stun_pkt_is_complete(pc_data, u_data_size, &b_pkt_is_complete))) {
- goto bail;
- }
- if (!b_pkt_is_complete) {
- TSK_DEBUG_INFO("The stream length is too short to contains a complete STUN/TURN packet");
- goto bail;
- }
- }
+ // TODO: /!\
+ // - When the requested transport is TCP/TLS then we will receive RAW data on the connected peer socket which means no way to guess the end-of-the message
+ // - No issue for when requested transport is UDP because we'll always have the data encapsulated in CHANNEL-DATA or DATA-INDICATION.
+ if (b_stream) {
+ if (!b_stream_appended) {
+ tsk_safeobj_lock(p_ss);
+ pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
+ if (pc_peer) {
+ p_stream_buff_in = tsk_object_ref(pc_peer->p_stream_buff_in);
+ }
+ else {
+ p_stream_buff_in = tsk_object_ref(p_ss->p_stream_buff_in);
+ }
+ tsk_safeobj_unlock(p_ss);
- // Parse the packet
- if ((ret = tnet_stun_pkt_read(pc_data, u_data_size, &p_pkt))) {
- goto bail;
- }
+ if ((ret = tsk_buffer_append(p_stream_buff_in, e->data, e->size))) {
+ goto bail;
+ }
+ b_stream_appended = tsk_true;
+ }
+ // Guard
+ if (p_stream_buff_in->size > kTurnStreamChunckMaxSize) {
+ TSK_DEBUG_ERROR("Too much data in the stream buffer: %u", (unsigned)p_stream_buff_in->size);
+ tsk_buffer_cleanup(p_stream_buff_in);
+ goto bail;
+ }
+ pc_data = p_stream_buff_in->data;
+ u_data_size = p_stream_buff_in->size;
+ }
- // Remove the parsed data
- if (p_stream_buff_in && p_pkt) {
- tsk_size_t u_pad_len = (p_pkt->u_length & 3) ? (4 - (p_pkt->u_length & 3)) : 0;
- tsk_buffer_remove(p_stream_buff_in, 0, kStunPktHdrSizeInOctets + p_pkt->u_length + u_pad_len);
- }
+ if (!TNET_STUN_BUFF_IS_STUN2(((const uint8_t*)pc_data), u_data_size)) {
+ // ChannelData ?
+ if (TNET_STUN_BUFF_IS_CHANNEL_DATA(((const uint8_t*)pc_data), u_data_size)) {
+ const uint8_t* _p_data = (const uint8_t*)pc_data;
+ // Channel Number in [0x4000 - 0x7FFF]
+ // rfc5766 - 11.6. Receiving a ChannelData Message
+ // rfc5766 - 11.4. The ChannelData Message
+ // If the message uses a value in the reserved range (0x8000 through 0xFFFF), then the message is silently discarded
+ static const tsk_size_t kChannelDataHdrSize = 4; // Channel Number(2 bytes) + Length (2 bytes)
+ uint16_t u_chan_num = tnet_ntohs_2(&_p_data[0]);
+ if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_channum, &u_chan_num))) {
+ uint16_t u_len = tnet_ntohs_2(&_p_data[2]);
+ if (u_len <= (u_data_size - kChannelDataHdrSize)) {
+ b_got_msg = tsk_true;
+ _tnet_turn_session_raise_event_recv_data(p_ss, pc_peer->id, &_p_data[kChannelDataHdrSize], u_len);
+ if (p_stream_buff_in) {
+ /* The padding is not reflected in the length
+ field of the ChannelData message, so the actual size of a ChannelData
+ message (including padding) is (4 + Length) rounded up to the nearest
+ multiple of 4. Over UDP, the padding is not required but MAY be
+ included.
+ */
+ tsk_size_t u_pad_len = (u_len & 3) ? (4 - (u_len & 3)) : 0;
+ tsk_buffer_remove(p_stream_buff_in, 0, kChannelDataHdrSize + u_len + u_pad_len);
+ }
+ }
+ else {
+ TSK_DEBUG_INFO("TURN channel data too short");
+ }
+ }
+ goto bail;
+ } // if (TNET_STUN_BUFF_IS_CHANNEL_DATA...
- if (p_pkt) {
- b_got_msg = tsk_true;
- if (p_pkt->e_type == tnet_stun_pkt_type_data_indication) {
- const tnet_stun_attr_vdata_t *pc_attr_data;
- const tnet_stun_attr_address_t *pc_attr_xpeer;
- const tnet_turn_peer_t *pc_peer;
- // XOR-PEER-ADDRESS (required)
- if ((ret = tnet_stun_pkt_attr_find_first(p_pkt, tnet_stun_attr_type_xor_peer_address, (const tnet_stun_attr_t**)&pc_attr_xpeer)) || !pc_attr_xpeer) {
- TSK_DEBUG_ERROR("XOR-PEER-ADDRESS missing in DATA-INDICATION");
- ret = -4;
- goto bail;
- }
- tsk_safeobj_lock(p_ss); // lock to make sure the list will not be modified
- if ((ret = _tnet_turn_peer_find_by_xpeer(p_ss->p_list_peers, pc_attr_xpeer, &pc_peer))) {
- tsk_safeobj_unlock(p_ss);
- goto bail;
- }
- tsk_safeobj_unlock(p_ss); // unlock()
- // DATA (required)
- if ((ret = tnet_stun_pkt_attr_find_first(p_pkt, tnet_stun_attr_type_data, (const tnet_stun_attr_t**)&pc_attr_data)) || !pc_attr_data) {
- TSK_DEBUG_ERROR("DATA missing in DATA-INDICAION");
- ret = -4;
- goto bail;
- }
-
- _tnet_turn_session_raise_event_recv_data(p_ss, pc_peer ? pc_peer->id : kTurnPeerIdInvalid, pc_attr_data->p_data_ptr, pc_attr_data->u_data_size);
- }
- else {
- tsk_bool_t b_processed;
- if ((ret = _tnet_turn_session_process_incoming_pkt(p_ss, p_pkt, &b_processed))) {
- goto bail;
- }
- if (!b_processed) {
- const tnet_turn_peer_t *pc_peer;
- tsk_safeobj_lock(p_ss);
- pc_peer = (const tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
- tsk_safeobj_unlock(p_ss); // unlock()
- // Forward to listeners (e.g. ICE context)
- _tnet_turn_session_raise_event_recv_data(p_ss, pc_peer ? pc_peer->id : kTurnPeerIdInvalid, pc_data, u_data_size);
- }
- }
- }
+ // Must never happen: Data must be received via CHANNEL-DATA or DATA-INDICATION
+ TSK_DEBUG_INFO("Calling unexpected code :(");
+
+ if (b_stream) {
+ tsk_safeobj_lock(p_ss);
+ pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
+ tsk_safeobj_unlock(p_ss);
+ }
+ _tnet_turn_session_raise_event_recv_data(p_ss, pc_peer ? pc_peer->id : kTurnPeerIdInvalid, pc_data, u_data_size);
+ if (p_stream_buff_in) {
+ tsk_buffer_cleanup(p_stream_buff_in);
+ }
+ goto bail;
+ } // if (!TNET_STUN_BUFF_IS_STUN2...
+
+ /*** At this step it means we have a STUN packet in the buffer ***/
+
+ // Make sure we have a complete packet in the buffer
+ if (b_stream) {
+ if ((ret = tnet_stun_pkt_is_complete(pc_data, u_data_size, &b_pkt_is_complete))) {
+ goto bail;
+ }
+ if (!b_pkt_is_complete) {
+ TSK_DEBUG_INFO("The stream length is too short to contains a complete STUN/TURN packet");
+ goto bail;
+ }
+ }
+
+ // Parse the packet
+ if ((ret = tnet_stun_pkt_read(pc_data, u_data_size, &p_pkt))) {
+ goto bail;
+ }
+
+ // Remove the parsed data
+ if (p_stream_buff_in && p_pkt) {
+ tsk_size_t u_pad_len = (p_pkt->u_length & 3) ? (4 - (p_pkt->u_length & 3)) : 0;
+ tsk_buffer_remove(p_stream_buff_in, 0, kStunPktHdrSizeInOctets + p_pkt->u_length + u_pad_len);
+ }
+
+ if (p_pkt) {
+ b_got_msg = tsk_true;
+ if (p_pkt->e_type == tnet_stun_pkt_type_data_indication) {
+ const tnet_stun_attr_vdata_t *pc_attr_data;
+ const tnet_stun_attr_address_t *pc_attr_xpeer;
+ const tnet_turn_peer_t *pc_peer;
+ // XOR-PEER-ADDRESS (required)
+ if ((ret = tnet_stun_pkt_attr_find_first(p_pkt, tnet_stun_attr_type_xor_peer_address, (const tnet_stun_attr_t**)&pc_attr_xpeer)) || !pc_attr_xpeer) {
+ TSK_DEBUG_ERROR("XOR-PEER-ADDRESS missing in DATA-INDICATION");
+ ret = -4;
+ goto bail;
+ }
+ tsk_safeobj_lock(p_ss); // lock to make sure the list will not be modified
+ if ((ret = _tnet_turn_peer_find_by_xpeer(p_ss->p_list_peers, pc_attr_xpeer, &pc_peer))) {
+ tsk_safeobj_unlock(p_ss);
+ goto bail;
+ }
+ tsk_safeobj_unlock(p_ss); // unlock()
+ // DATA (required)
+ if ((ret = tnet_stun_pkt_attr_find_first(p_pkt, tnet_stun_attr_type_data, (const tnet_stun_attr_t**)&pc_attr_data)) || !pc_attr_data) {
+ TSK_DEBUG_ERROR("DATA missing in DATA-INDICAION");
+ ret = -4;
+ goto bail;
+ }
+
+ _tnet_turn_session_raise_event_recv_data(p_ss, pc_peer ? pc_peer->id : kTurnPeerIdInvalid, pc_attr_data->p_data_ptr, pc_attr_data->u_data_size);
+ }
+ else {
+ tsk_bool_t b_processed;
+ if ((ret = _tnet_turn_session_process_incoming_pkt(p_ss, p_pkt, &b_processed))) {
+ goto bail;
+ }
+ if (!b_processed) {
+ const tnet_turn_peer_t *pc_peer;
+ tsk_safeobj_lock(p_ss);
+ pc_peer = (const tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_fd, &e->local_fd);
+ tsk_safeobj_unlock(p_ss); // unlock()
+ // Forward to listeners (e.g. ICE context)
+ _tnet_turn_session_raise_event_recv_data(p_ss, pc_peer ? pc_peer->id : kTurnPeerIdInvalid, pc_data, u_data_size);
+ }
+ }
+ }
bail:
- // Handle next message in the stream buffer
- if (ret == 0 && b_got_msg && b_stream && p_stream_buff_in && p_stream_buff_in->size > 0) {
- goto handle_data;
- }
+ // Handle next message in the stream buffer
+ if (ret == 0 && b_got_msg && b_stream && p_stream_buff_in && p_stream_buff_in->size > 0) {
+ goto handle_data;
+ }
- TSK_OBJECT_SAFE_FREE(p_pkt);
- TSK_OBJECT_SAFE_FREE(p_stream_buff_in);
- p_ss->cb.e.pc_enet = tsk_null;
+ TSK_OBJECT_SAFE_FREE(p_pkt);
+ TSK_OBJECT_SAFE_FREE(p_stream_buff_in);
+ p_ss->cb.e.pc_enet = tsk_null;
return ret;
}
@@ -2288,36 +2294,36 @@ static int _tnet_turn_session_timer_callback(const void* pc_arg, tsk_timer_id_t
}
tnet_turn_session_t* p_ss = (tnet_turn_session_t*)pc_arg;
- tnet_turn_peer_t* pc_peer;
- int ret = 0;
+ tnet_turn_peer_t* pc_peer;
+ int ret = 0;
tsk_safeobj_lock(p_ss); // must
- if (p_ss->timer.rtt.alloc.id == timer_id) {
- RETRANSMIT(p_ss, alloc, kTurnPeerIdInvalid);
+ if (p_ss->timer.rtt.alloc.id == timer_id) {
+ RETRANSMIT(p_ss, alloc, kTurnPeerIdInvalid);
}
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_timer_rtt_chanbind, &timer_id))) {
- RETRANSMIT(pc_peer, chanbind, pc_peer->id);
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_timer_rtt_chanbind, &timer_id))) {
+ RETRANSMIT(pc_peer, chanbind, pc_peer->id);
}
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_timer_rtt_createperm, &timer_id))) {
- RETRANSMIT(pc_peer, createperm, pc_peer->id);
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_timer_rtt_createperm, &timer_id))) {
+ RETRANSMIT(pc_peer, createperm, pc_peer->id);
}
- else if (p_ss->timer.rtt.refresh.id == timer_id) {
- RETRANSMIT(p_ss, refresh, kTurnPeerIdInvalid);
+ else if (p_ss->timer.rtt.refresh.id == timer_id) {
+ RETRANSMIT(p_ss, refresh, kTurnPeerIdInvalid);
}
- else if (p_ss->timer.u_timer_id_refresh == timer_id) {
- if ((ret = _tnet_turn_session_send_refresh(p_ss))) {
- goto bail;
- }
+ else if (p_ss->timer.u_timer_id_refresh == timer_id) {
+ if ((ret = _tnet_turn_session_send_refresh(p_ss))) {
+ goto bail;
+ }
}
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_timer_fresh_chanbind, &timer_id))) {
- if ((ret = tnet_turn_session_chanbind(p_ss, pc_peer->id))) {
- goto bail;
- }
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_timer_fresh_chanbind, &timer_id))) {
+ if ((ret = tnet_turn_session_chanbind(p_ss, pc_peer->id))) {
+ goto bail;
+ }
+ }
+ else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_timer_fresh_createperm, &timer_id))) {
+ if ((ret = _tnet_turn_session_send_permission(p_ss, pc_peer))) {
+ goto bail;
+ }
}
- else if ((pc_peer = (tnet_turn_peer_t*)tsk_list_find_object_by_pred(p_ss->p_list_peers, __pred_find_peer_by_timer_fresh_createperm, &timer_id))) {
- if ((ret = _tnet_turn_session_send_permission(p_ss, pc_peer))) {
- goto bail;
- }
- }
bail:
tsk_safeobj_unlock(p_ss);
@@ -2326,71 +2332,71 @@ bail:
static int _tnet_turn_peer_create(const char* pc_peer_ip, uint16_t u_peer_port, tsk_bool_t b_ipv6, struct tnet_turn_peer_s **pp_peer)
{
- extern const tsk_object_def_t *tnet_turn_peer_def_t;
- static tnet_turn_peer_id_t __l_peer_id = 0;
- tnet_stun_addr_t peer_addr;
- int ret;
- if (!pc_peer_ip || !u_peer_port || !pp_peer) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- if ((ret = tnet_stun_utils_inet_pton(b_ipv6, pc_peer_ip, &peer_addr))) {
+ extern const tsk_object_def_t *tnet_turn_peer_def_t;
+ static tnet_turn_peer_id_t __l_peer_id = 0;
+ tnet_stun_addr_t peer_addr;
+ int ret;
+ if (!pc_peer_ip || !u_peer_port || !pp_peer) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ if ((ret = tnet_stun_utils_inet_pton(b_ipv6, pc_peer_ip, &peer_addr))) {
TSK_DEBUG_ERROR("inet_pton(%s,IPv6=%d) failed", pc_peer_ip, b_ipv6);
goto bail;
}
- if (!(*pp_peer = tsk_object_new(tnet_turn_peer_def_t))) {
- TSK_DEBUG_ERROR("Failed to create TURN peer object");
- return -2;
- }
- (*pp_peer)->p_addr_ip = tsk_strdup(pc_peer_ip);
- memcpy((*pp_peer)->addr_ip, peer_addr, sizeof(peer_addr));
- (*pp_peer)->u_addr_port = u_peer_port;
- (*pp_peer)->b_ipv6 = b_ipv6;
- tsk_atomic_inc(&__l_peer_id);
- (*pp_peer)->id = __l_peer_id;
- (*pp_peer)->timer.rtt.chanbind.id = TSK_INVALID_TIMER_ID;
- (*pp_peer)->timer.rtt.createperm.id = TSK_INVALID_TIMER_ID;
- (*pp_peer)->timer.rtt.chanbind.u_timeout = kStunUdpRetransmitTimoutMinInMs;
- (*pp_peer)->timer.rtt.createperm.u_timeout = kStunUdpRetransmitTimoutMinInMs;
- (*pp_peer)->timer.fresh.chanbind.id = TSK_INVALID_TIMER_ID;
- (*pp_peer)->timer.fresh.createperm.id = TSK_INVALID_TIMER_ID;
- (*pp_peer)->timer.fresh.chanbind.u_timeout = kTurnChannelBindingTimeOutInSec * 1000;
- (*pp_peer)->timer.fresh.createperm.u_timeout = kTurnPermissionTimeOutInSec * 1000;
- (*pp_peer)->e_chanbind_state = tnet_stun_state_none;
- (*pp_peer)->e_createperm_state = tnet_stun_state_none;
+ if (!(*pp_peer = tsk_object_new(tnet_turn_peer_def_t))) {
+ TSK_DEBUG_ERROR("Failed to create TURN peer object");
+ return -2;
+ }
+ (*pp_peer)->p_addr_ip = tsk_strdup(pc_peer_ip);
+ memcpy((*pp_peer)->addr_ip, peer_addr, sizeof(peer_addr));
+ (*pp_peer)->u_addr_port = u_peer_port;
+ (*pp_peer)->b_ipv6 = b_ipv6;
+ tsk_atomic_inc(&__l_peer_id);
+ (*pp_peer)->id = __l_peer_id;
+ (*pp_peer)->timer.rtt.chanbind.id = TSK_INVALID_TIMER_ID;
+ (*pp_peer)->timer.rtt.createperm.id = TSK_INVALID_TIMER_ID;
+ (*pp_peer)->timer.rtt.chanbind.u_timeout = kStunUdpRetransmitTimoutMinInMs;
+ (*pp_peer)->timer.rtt.createperm.u_timeout = kStunUdpRetransmitTimoutMinInMs;
+ (*pp_peer)->timer.fresh.chanbind.id = TSK_INVALID_TIMER_ID;
+ (*pp_peer)->timer.fresh.createperm.id = TSK_INVALID_TIMER_ID;
+ (*pp_peer)->timer.fresh.chanbind.u_timeout = kTurnChannelBindingTimeOutInSec * 1000;
+ (*pp_peer)->timer.fresh.createperm.u_timeout = kTurnPermissionTimeOutInSec * 1000;
+ (*pp_peer)->e_chanbind_state = tnet_stun_state_none;
+ (*pp_peer)->e_createperm_state = tnet_stun_state_none;
bail:
- return ret;
+ return ret;
}
static int _tnet_turn_peer_find_by_xpeer(const tnet_turn_peers_L_t* pc_peers, const tnet_stun_attr_address_t* pc_xpeer, const tnet_turn_peer_t **ppc_peer)
{
- const tsk_list_item_t *pc_item;
- const tnet_turn_peer_t *pc_peer;
- if (!pc_peers || !pc_xpeer || !ppc_peer) {
- TSK_DEBUG_ERROR("Invalid parameter");
- return -1;
- }
- *ppc_peer = tsk_null;
- tsk_list_foreach(pc_item, pc_peers) {
- pc_peer = (const tnet_turn_peer_t *)pc_item->data;
- if (pc_peer->u_addr_port == pc_xpeer->u_port) {
- if (tnet_stun_utils_buff_cmp(
- pc_peer->addr_ip, pc_peer->b_ipv6 ? 16 : 4,
- pc_xpeer->address, (pc_xpeer->e_family == tnet_stun_address_family_ipv6) ? 16 : 4) == 0) {
- *ppc_peer = pc_peer;
- return 0;
- }
- }
- }
- return 0;
+ const tsk_list_item_t *pc_item;
+ const tnet_turn_peer_t *pc_peer;
+ if (!pc_peers || !pc_xpeer || !ppc_peer) {
+ TSK_DEBUG_ERROR("Invalid parameter");
+ return -1;
+ }
+ *ppc_peer = tsk_null;
+ tsk_list_foreach(pc_item, pc_peers) {
+ pc_peer = (const tnet_turn_peer_t *)pc_item->data;
+ if (pc_peer->u_addr_port == pc_xpeer->u_port) {
+ if (tnet_stun_utils_buff_cmp(
+ pc_peer->addr_ip, pc_peer->b_ipv6 ? 16 : 4,
+ pc_xpeer->address, (pc_xpeer->e_family == tnet_stun_address_family_ipv6) ? 16 : 4) == 0) {
+ *ppc_peer = pc_peer;
+ return 0;
+ }
+ }
+ }
+ return 0;
}
static tsk_object_t* tnet_turn_session_ctor(tsk_object_t * self, va_list * app)
{
tnet_turn_session_t *p_ss = (tnet_turn_session_t *)self;
if (p_ss) {
- tsk_safeobj_init(p_ss);
+ tsk_safeobj_init(p_ss);
}
return self;
}
@@ -2398,41 +2404,41 @@ static tsk_object_t* tnet_turn_session_dtor(tsk_object_t * self)
{
tnet_turn_session_t *p_ss = (tnet_turn_session_t *)self;
if (p_ss) {
- // stop()
- tnet_turn_session_stop(p_ss);
- // timer.free()
- TSK_OBJECT_SAFE_FREE(p_ss->timer.p_mgr);
- // cred.free()
- TSK_FREE(p_ss->cred.p_usr_name);
- TSK_FREE(p_ss->cred.p_pwd);
- // others.free()
- TSK_OBJECT_SAFE_FREE(p_ss->p_pkt_alloc);
- TSK_OBJECT_SAFE_FREE(p_ss->p_pkt_refresh);
- TSK_OBJECT_SAFE_FREE(p_ss->p_lcl_sock);
-
- TSK_FREE(p_ss->p_buff_chandata_ptr);
- TSK_FREE(p_ss->p_buff_send_ptr);
- TSK_FREE(p_ss->p_rel_ip);
- TSK_FREE(p_ss->p_srflx_ip);
- TSK_FREE(p_ss->p_srv_host);
-
- if (p_ss->p_transport) {
- tnet_transport_shutdown(p_ss->p_transport);
- TSK_OBJECT_SAFE_FREE(p_ss->p_transport);
- }
-
- TSK_OBJECT_SAFE_FREE(p_ss->p_list_peers);
- TSK_OBJECT_SAFE_FREE(p_ss->p_stream_buff_in);
+ // stop()
+ tnet_turn_session_stop(p_ss);
+ // timer.free()
+ TSK_OBJECT_SAFE_FREE(p_ss->timer.p_mgr);
+ // cred.free()
+ TSK_FREE(p_ss->cred.p_usr_name);
+ TSK_FREE(p_ss->cred.p_pwd);
+ // others.free()
+ TSK_OBJECT_SAFE_FREE(p_ss->p_pkt_alloc);
+ TSK_OBJECT_SAFE_FREE(p_ss->p_pkt_refresh);
+ TSK_OBJECT_SAFE_FREE(p_ss->p_lcl_sock);
+
+ TSK_FREE(p_ss->p_buff_chandata_ptr);
+ TSK_FREE(p_ss->p_buff_send_ptr);
+ TSK_FREE(p_ss->p_rel_ip);
+ TSK_FREE(p_ss->p_srflx_ip);
+ TSK_FREE(p_ss->p_srv_host);
+
+ if (p_ss->p_transport) {
+ tnet_transport_shutdown(p_ss->p_transport);
+ TSK_OBJECT_SAFE_FREE(p_ss->p_transport);
+ }
+
+ TSK_OBJECT_SAFE_FREE(p_ss->p_list_peers);
+ TSK_OBJECT_SAFE_FREE(p_ss->p_stream_buff_in);
TSK_OBJECT_SAFE_FREE(p_ss->p_stream_buff_out);
-
+
TSK_OBJECT_SAFE_FREE(p_ss->proxy.info);
- TSK_FREE(p_ss->ssl.path_priv);
- TSK_FREE(p_ss->ssl.path_pub);
- TSK_FREE(p_ss->ssl.path_ca);
+ TSK_FREE(p_ss->ssl.path_priv);
+ TSK_FREE(p_ss->ssl.path_pub);
+ TSK_FREE(p_ss->ssl.path_ca);
- tsk_safeobj_deinit(p_ss);
- TSK_DEBUG_INFO("*** TURN Session destroyed ***");
+ tsk_safeobj_deinit(p_ss);
+ TSK_DEBUG_INFO("*** TURN Session destroyed ***");
}
return self;
}
@@ -2456,7 +2462,7 @@ static tsk_object_t* tnet_turn_peer_ctor(tsk_object_t * self, va_list * app)
{
tnet_turn_peer_t *p_peer = (tnet_turn_peer_t *)self;
if (p_peer) {
-
+
}
return self;
}
@@ -2464,13 +2470,13 @@ static tsk_object_t* tnet_turn_peer_dtor(tsk_object_t * self)
{
tnet_turn_peer_t *p_peer = (tnet_turn_peer_t *)self;
if (p_peer) {
- TSK_FREE(p_peer->p_addr_ip);
- TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_chanbind);
- TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_createperm);
- TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_sendind);
- TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_connect);
- TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_connbind);
- TSK_OBJECT_SAFE_FREE(p_peer->p_stream_buff_in);
+ TSK_FREE(p_peer->p_addr_ip);
+ TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_chanbind);
+ TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_createperm);
+ TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_sendind);
+ TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_connect);
+ TSK_OBJECT_SAFE_FREE(p_peer->p_pkt_connbind);
+ TSK_OBJECT_SAFE_FREE(p_peer->p_stream_buff_in);
TSK_OBJECT_SAFE_FREE(p_peer->p_stream_buff_out);
#if PRINT_DESTROYED_MSG || 1
TSK_DEBUG_INFO("*** TURN peer destroyed ***");
diff --git a/tinyNET/src/turn/tnet_turn_session.h b/tinyNET/src/turn/tnet_turn_session.h
index fa4a030..7357bb1 100755
--- a/tinyNET/src/turn/tnet_turn_session.h
+++ b/tinyNET/src/turn/tnet_turn_session.h
@@ -33,34 +33,33 @@ struct tnet_proxyinfo_s;
enum tnet_socket_type_e;
#define kTurnPeerIdInvalid -1
-typedef enum tnet_turn_session_event_type_e
-{
- tnet_turn_session_event_type_alloc_ok,
- tnet_turn_session_event_type_alloc_nok,
- tnet_turn_session_event_type_refresh_ok,
- tnet_turn_session_event_type_refresh_nok,
- tnet_turn_session_event_type_perm_ok,
- tnet_turn_session_event_type_perm_nok,
- tnet_turn_session_event_type_recv_data,
- tnet_turn_session_event_type_chanbind_ok,
- tnet_turn_session_event_type_chanbind_nok,
- tnet_turn_session_event_type_connect_ok,
- tnet_turn_session_event_type_connect_nok,
- tnet_turn_session_event_type_connectionbind_ok,
- tnet_turn_session_event_type_connectionbind_nok,
+typedef enum tnet_turn_session_event_type_e {
+ tnet_turn_session_event_type_alloc_ok,
+ tnet_turn_session_event_type_alloc_nok,
+ tnet_turn_session_event_type_refresh_ok,
+ tnet_turn_session_event_type_refresh_nok,
+ tnet_turn_session_event_type_perm_ok,
+ tnet_turn_session_event_type_perm_nok,
+ tnet_turn_session_event_type_recv_data,
+ tnet_turn_session_event_type_chanbind_ok,
+ tnet_turn_session_event_type_chanbind_nok,
+ tnet_turn_session_event_type_connect_ok,
+ tnet_turn_session_event_type_connect_nok,
+ tnet_turn_session_event_type_connectionbind_ok,
+ tnet_turn_session_event_type_connectionbind_nok,
}
tnet_turn_session_event_type_t;
typedef struct tnet_turn_session_event_xs {
- enum tnet_turn_session_event_type_e e_type;
- tnet_turn_peer_id_t u_peer_id;
- const void* pc_usr_data;
- const struct tnet_transport_event_s* pc_enet;
- struct tnet_turn_session_s* pc_session;
- struct {
- const void* pc_data_ptr;
- tsk_size_t u_data_size;
- } data;
+ enum tnet_turn_session_event_type_e e_type;
+ tnet_turn_peer_id_t u_peer_id;
+ const void* pc_usr_data;
+ const struct tnet_transport_event_s* pc_enet;
+ struct tnet_turn_session_s* pc_session;
+ struct {
+ const void* pc_data_ptr;
+ tsk_size_t u_data_size;
+ } data;
} tnet_turn_session_event_xt;
typedef int (*tnet_turn_session_callback_f)(const struct tnet_turn_session_event_xs *e);
OpenPOWER on IntegriCloud