1 /* Copyright 2013 Akira Ohta (akohta001@gmail.com)
2 This file is part of ntch.
4 The ntch is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 The ntch is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with ntch. If not, see <http://www.gnu.org/licenses/>.
18 #include <sys/types.h>
19 #include <sys/socket.h>
24 #include <arpa/inet.h>
29 #include "utils/nt_std_t.h"
30 #include "net/nt_socket.h"
32 void nt_socket_free(nt_socket_tp socketp)
37 nt_socket_tp nt_socket_init(int port, char *addr)
40 struct addrinfo addr_limit;
41 struct addrinfo *addr_out, *addr_list;
42 struct sockaddr_in *s_addr;
43 struct sockaddr_in6 *s_addr6;
46 struct hostent *hostinfo;
49 nt_socket_tp ptr = malloc(sizeof(nt_socket_t));
53 ptr->h_mutex = nt_mutex_get_one_time_handle(NT_MUTEX_ROOT_NAME_NET);
58 if(!nt_mutex_add_mbs_moniker(ptr->h_mutex, addr)){
63 ptr->_sockaddr_in.sin_port = htons(port);
66 memset(&addr_limit, 0, sizeof(addr_limit));
67 addr_limit.ai_family = AF_UNSPEC;
68 addr_limit.ai_socktype = SOCK_STREAM;
69 addr_limit.ai_protocol = IPPROTO_TCP;
70 if(0 != getaddrinfo(addr, NULL, &addr_limit, &addr_out)){
75 for(addr_list = addr_out; addr_list != NULL;
76 addr_list = addr_list->ai_next){
77 if(!addr_list->ai_addr)
79 switch(addr_list->ai_family){
81 assert(addr_list->ai_addrlen == sizeof(struct sockaddr_in));
82 ptr->addr_family = AF_INET;
83 s_addr = (struct sockaddr_in*)addr_list->ai_addr;
84 ptr->_sockaddr_in.sin_family = AF_INET;
85 memcpy(&ptr->_sockaddr_in.sin_addr.s_addr,
86 &s_addr->sin_addr.s_addr, sizeof(struct in_addr));
89 assert(addr_list->ai_addrlen == sizeof(struct sockaddr_in6));
90 ptr->addr_family = AF_INET6;
91 s_addr6 = (struct sockaddr_in6*)addr_list->ai_addr;
92 ptr->_sockaddr_in6.sin6_family = AF_INET6;
93 memcpy(&ptr->_sockaddr_in6.sin6_addr.s6_addr,
94 s_addr6->sin6_addr.s6_addr, sizeof(struct in6_addr));
98 freeaddrinfo(addr_out);
100 ptr->_sockaddr_in.sin_family = AF_INET;
101 ptr->_sockaddr_in.sin_addr.s_addr = inet_addr(addr);
102 if(ptr->_sockaddr_in.sin_addr.s_addr == 0xffffffff){
103 hostinfo = gethostbyname(addr);
106 if(hostinfo->h_addrtype != AF_INET)
108 if(hostinfo->h_addr_list[0] == NULL)
110 memcpy(&ptr->_sockaddr_in.sin_addr.s_addr,
111 hostinfo->h_addr_list[0], 4);
117 int nt_socket_connect(nt_socket_tp socketp, char* data, int data_len)
124 switch(socketp->addr_family){
126 len = sizeof(socketp->_sockaddr_in);
129 len = sizeof(socketp->_sockaddr_in6);
134 sockfd = socket(socketp->addr_family, SOCK_STREAM, 0);
139 sockfd = socket(AF_INET, SOCK_STREAM, 0);
143 len = sizeof(socketp->_sockaddr_in);
145 nt_mutex_lock(socketp->h_mutex);
146 result = connect(sockfd,
147 (struct sockaddr *)&(socketp->_sockaddr_in), len);
148 nt_mutex_unlock(socketp->h_mutex);
154 result = write(sockfd, data, data_len);