summaryrefslogtreecommitdiffstats
path: root/branches/1.0/tinyNET/src/tnet_socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'branches/1.0/tinyNET/src/tnet_socket.c')
-rw-r--r--branches/1.0/tinyNET/src/tnet_socket.c326
1 files changed, 0 insertions, 326 deletions
diff --git a/branches/1.0/tinyNET/src/tnet_socket.c b/branches/1.0/tinyNET/src/tnet_socket.c
deleted file mode 100644
index 33dc807..0000000
--- a/branches/1.0/tinyNET/src/tnet_socket.c
+++ /dev/null
@@ -1,326 +0,0 @@
-/*
-* Copyright (C) 2009-2010 Mamadou Diop.
-*
-* Contact: Mamadou Diop <diopmamadou(at)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.
-*
-*/
-
-/**@file tnet.h
- * @brief Protocol agnostic socket.
- *
- * @author Mamadou Diop <diopmamadou(at)doubango.org>
- *
- * @date Created: Sat Nov 8 16:54:58 2009 mdiop
- */
-
-#include "tnet_socket.h"
-
-#include "tnet_utils.h"
-
-#include "tsk_string.h"
-#include "tsk_debug.h"
-
-#include <string.h>
-
-/**@defgroup tnet_socket_group Protocol agnostic socket
-*
-*
-* <h2>10.1 Sockets</h2>
-* For performance reason, all sockets created using tinyNET are non-blocking by default.
-* The newly created socket will be automatically bound to associate it with an IP address and port number. @ref tnet_socket_create() function is used to create and bind a
-* non-blocking socket. You should use @ref tnet_socket_create_2() function to control whether the socket should be bound or not. The same function is used to force the stack to create a blocking socket.<br>
-* A socket object is defined like this:<br>
-*
-* @code
-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_socket_t;
-* @endcode
-* To create a socket:
-* @code
-// (create udp ipv4 or ipv6 socket)
-tnet_socket_t* socket = tnet_socket_create(
- TNET_SOCKET_HOST_ANY, // local ip address/hostname to bind to
- TNET_SOCKET_PORT_ANY, // local port number to bind to
- tnet_socket_type_udp_ipv46 // the socket type (IPv4 or IPv6)
- );
-// TNET_SOCKET_HOST_ANY --> bind to "0.0.0.0" or "::"
-// TNET_SOCKET_PORT_ANY --> bind to any available port
-* @endcode
-
-* <b>TNET_SOCKET_TYPE_IS_*()</b> macros are used to determine:
-* - The socket type (stream, dgram),
-* - The socket protocol (udp, tcp, tls, sctp, ipsec),
-* - The IP version (ipv6, ipv4),
-* - …
-* <br>
-* A socket is a well-defined object and should be destroyed using @a TSK_DECLARE_SAFE_FREE() macro.
-* A socket will be automatically closed when destroyed.
-*
-*/
-
-/**@ingroup tnet_socket_group
-* Creates a new socket.
-* To check that the returned socket is valid use @ref TNET_SOCKET_IS_VALID function.
-* @param host FQDN (e.g. www.doubango.org) or IPv4/IPv6 IP string.
-* @param port The local/remote port used to receive/send data. Set the port value to @ref TNET_SOCKET_PORT_ANY to bind to a random port.
-* @param type The type of the socket. See @ref tnet_socket_type_t.
-* @param nonblocking Indicates whether to create non-blocking socket.
-* @param bindsocket Indicates whether to bind the newly created socket or not.
-* @retval @ref tnet_socket_t object.
-* @sa @ref tnet_socket_create.
-*/
-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)
-{
- return tsk_object_new(tnet_socket_def_t, host, port, type, nonblocking, bindsocket);
-}
-
-/**@ingroup tnet_socket_group
-* Creates a non-blocking socket and bind it.
-* To check that the returned socket is valid use @ref TNET_SOCKET_IS_VALID function.
-* @param host FQDN (e.g. www.doubango.org) or IPv4/IPv6 IP string.
-* @param port The local/remote port used to receive/send data. Set the port value to @ref TNET_SOCKET_PORT_ANY to bind to a random port.
-* @param type The type of the socket. See @ref tnet_socket_type_t.
-* @retval @ref tnet_socket_t object.
-*/
-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);
-}
-
-
-
-
-/**@ingroup tnet_socket_group
- * Closes a socket.
- * @param sock The socket to close.
- * @retval Zero if succeed and nonzero error code otherwise.
-**/
-int tnet_socket_close(tnet_socket_t *sock)
-{
- return tnet_sockfd_close(&(sock->fd));
-}
-
-int tnet_socket_set_tlsfiles(tnet_socket_tls_t* socket, int isClient, const char* tlsfile_ca, const char* tlsfile_pvk, const char* tlsfile_pbk)
-{
- if(socket){
- return -1;
- }
-
- if(!TNET_SOCKET_TYPE_IS_TLS(socket->type)){
- TSK_DEBUG_ERROR("Not TLS socket.");
- return -2;
- }
-
- if(socket->tlshandle){
- TSK_DEBUG_ERROR("TLS files already set.");
- return -3;
- }
-
- if((socket->tlshandle = tnet_sockfd_set_tlsfiles(socket->fd, isClient, tlsfile_ca, tlsfile_pvk, tlsfile_pbk))){
- return 0;
- }
- else{
- return -4;
- }
-}
-
-//=================================================================================================
-// SOCKET object definition
-//
-static tsk_object_t* tnet_socket_ctor(tsk_object_t * self, va_list * app)
-{
- tnet_socket_t *sock = self;
- if(sock){
- int status;
- tsk_bool_t nonblocking;
- tsk_bool_t bindsocket;
- tsk_istr_t port;
- struct addrinfo *result = 0;
- struct addrinfo *ptr = 0;
- struct addrinfo hints;
- tnet_host_t local_hostname;
-
- const char *host = va_arg(*app, const char*);
-#if defined(__GNUC__)
- sock->port = (tnet_port_t)va_arg(*app, unsigned);
-#else
- sock->port = va_arg(*app, tnet_port_t);
-#endif
- tsk_itoa(sock->port, &port);
- sock->type = va_arg(*app, tnet_socket_type_t);
- nonblocking = va_arg(*app, tsk_bool_t);
- bindsocket = va_arg(*app, tsk_bool_t);
-
- 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);
- }
- //if((status = tnet_gethostname(&local_hostname)))
- //{
- // TNET_PRINT_LAST_ERROR("gethostname have failed.");
- // goto bail;
- //}
- }
-
- /* 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
-#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 = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
- if(ptr->ai_family != AF_INET6 && ptr->ai_family != AF_INET){
- continue;
- }
-
- if(bindsocket){
- /* Bind the socket */
- if((status = bind(sock->fd, ptr->ai_addr, ptr->ai_addrlen))){
- TNET_PRINT_LAST_ERROR("bind have failed.");
- tnet_socket_close(sock);
- continue;
- }
-
- /* Get local IP string. */
- if(status = tnet_get_ip_n_port(sock->fd , &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;
- }
-// else{
-//#if TNET_UNDER_WINDOWS
-// int index;
-// if((index = tsk_strindexOf(sock->ip, tsk_strlen(sock->ip), "%")) > 0){
-// *(sock->ip + index) = '\0';
-// }
-//#endif
-// }
- }
-
- /* 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;
- }
-
- /* To avoid "Address already in use" error */
- {
-#if defined(SOLARIS)
- char yes = '1';
-#else
- int yes = 1;
-#endif
- if(setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes, sizeof(int))){
- TNET_PRINT_LAST_ERROR("setsockopt(SO_REUSEADDR) have failed.");
- }
- }
-
- /* 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 && TNET_SOCKET_IS_VALID(sock)){
- tnet_socket_close(sock);
- }
-
- }
- return self;
-}
-
-static tsk_object_t* tnet_socket_dtor(tsk_object_t * self)
-{
- tnet_socket_t *sock = self;
-
- if(sock){
- /* Close the socket. */
- if(sock->fd > 0){
- tnet_socket_close(sock);
- }
- /* Clean up TLS handle*/
- if(sock->tlshandle){
- TSK_OBJECT_SAFE_FREE(sock->tlshandle);
- }
- }
-
-
- return self;
-}
-
-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;
-
-
OpenPOWER on IntegriCloud