1 /*
2 vconnect.c
3 Copyright (C) 2017 Belledonne Communications SARL
4 
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18 */
19 
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 
26 #include "bctoolbox/vconnect.h"
27 #include "bctoolbox/port.h"
28 #include "bctoolbox/logging.h"
29 #include <sys/types.h>
30 #include <stdarg.h>
31 #include <errno.h>
32 
33 
34 
35 
36 /**============================================================
37  * Wrappers around default libc calls used to handle windows
38  * differences in function prototypes.
39  *=============================================================*/
40 
vsocket_socket(int socket_family,int socket_type,int protocol)41 static bctbx_socket_t vsocket_socket(int socket_family, int socket_type, int protocol){
42 	return socket(socket_family, socket_type, protocol);
43 }
44 
45 
46 
vsocket_connect(bctbx_socket_t sock,const struct sockaddr * address,socklen_t address_len)47 static int vsocket_connect(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len){
48 	#ifdef _WIN32
49 		return connect(sock, address, (int)address_len);
50 	#else
51 		return connect(sock, address, address_len);
52 	#endif
53 }
54 
55 
vsocket_bind(bctbx_socket_t sock,const struct sockaddr * address,socklen_t address_len)56 static int vsocket_bind(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len){
57 	#ifdef _WIN32
58 		return bind(sock, address, (int)address_len);
59 	#else
60 		return bind(sock, address, address_len);
61 	#endif
62 }
63 
64 
vsocket_getsockname(bctbx_socket_t sockfd,struct sockaddr * addr,socklen_t * addrlen)65 static int vsocket_getsockname(bctbx_socket_t sockfd, struct sockaddr *addr, socklen_t *addrlen){
66 	#ifdef _WIN32
67 		return getsockname(sockfd, addr, (int*)addrlen);
68 	#else
69 		return getsockname(sockfd, addr, addrlen);
70 	#endif
71 }
72 
vsocket_getsockopt(bctbx_socket_t sockfd,int level,int optname,void * optval,socklen_t * optlen)73 static int vsocket_getsockopt(bctbx_socket_t sockfd, int level, int optname,
74 						void *optval, socklen_t* optlen){
75 	#ifdef _WIN32
76 		return getsockopt(sockfd, level, optname, (char*)optval,  (int*)optlen);
77 	#else
78 		return getsockopt(sockfd, level, optname, optval,  optlen);
79 	#endif
80 
81 }
82 
83 
vsocket_setsockopt(bctbx_socket_t sockfd,int level,int optname,const void * optval,socklen_t optlen)84 static int vsocket_setsockopt(bctbx_socket_t sockfd, int level, int optname,
85 							const void *optval, socklen_t optlen){
86 	#ifdef _WIN32
87 		return setsockopt(sockfd, level, optname, (char*)optval,  (int)optlen);
88 	#else
89 		return setsockopt(sockfd, level, optname, optval,  optlen);
90 	#endif
91 
92 }
93 
vsocket_close(bctbx_socket_t sock)94 static int vsocket_close(bctbx_socket_t sock){
95 	#ifdef _WIN32
96 	return closesocket(sock);
97 	#else
98 	return close(sock);
99 	#endif
100 }
101 
vsocket_shutdown(bctbx_socket_t sock,int how)102 static int vsocket_shutdown(bctbx_socket_t sock, int how){
103 	return shutdown(sock, how);
104 }
105 
106 
107 #if	!defined(_WIN32) && !defined(_WIN32_WCE)
vsocket_error(int err)108 static char* vsocket_error(int err){
109 	 return strerror (err);
110 }
111 
112 #else
113 
vsocket_error(int err)114 static  char* vsocket_error(int err){
115 	 return (char*)__bctbx_getWinSocketError(err);
116  }
117 #endif
118 
119 /**===================================================
120  * Socket API default methods pointer definition.
121  * ===================================================*/
122 
123 static const bctbx_vsocket_methods_t bcSocketAPI = {
124 	vsocket_socket,
125 	vsocket_connect,
126 	vsocket_bind,
127 	vsocket_getsockname,
128 	vsocket_getsockopt,
129 	vsocket_setsockopt,
130 	vsocket_close,
131 	vsocket_error,
132 	vsocket_shutdown,
133 };
134 
135 
136 static bctbx_vsocket_api_t bcvSocket = {
137 	"bctbx_socket",          /* vSockName */
138 	&bcSocketAPI,			/*pSocketMethods */
139 };
140 
141 
142 
143 /* Pointer to default socket methods initialized to standard libc implementation here.*/
144 static  bctbx_vsocket_api_t *pDefaultvSocket = &bcvSocket;
145 
146 
bctbx_socket(int socket_family,int socket_type,int protocol)147 bctbx_socket_t bctbx_socket(int socket_family, int socket_type, int protocol){
148 	return pDefaultvSocket->pSocketMethods->pFuncSocket( socket_family, socket_type, protocol);
149 }
150 
151 
bctbx_socket_close(bctbx_socket_t sock)152 int bctbx_socket_close(bctbx_socket_t sock){
153 	return pDefaultvSocket->pSocketMethods->pFuncClose(sock);
154 }
155 
156 
bctbx_bind(bctbx_socket_t sock,const struct sockaddr * address,socklen_t address_len)157 int bctbx_bind(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len){
158 	return pDefaultvSocket->pSocketMethods->pFuncBind(sock, address, address_len);
159 
160 }
161 
162 
bctbx_connect(bctbx_socket_t sock,const struct sockaddr * address,socklen_t address_len)163 int bctbx_connect(bctbx_socket_t sock, const struct sockaddr *address, socklen_t address_len){
164 	return pDefaultvSocket->pSocketMethods->pFuncConnect(sock, address, address_len);
165 }
166 
bctbx_getsockname(bctbx_socket_t sockfd,struct sockaddr * addr,socklen_t * addrlen)167 int bctbx_getsockname(bctbx_socket_t sockfd, struct sockaddr *addr, socklen_t *addrlen){
168 	return pDefaultvSocket->pSocketMethods->pFuncGetSockName(sockfd, addr, addrlen);
169 }
170 
171 
bctbx_getsockopt(bctbx_socket_t sockfd,int level,int optname,void * optval,socklen_t * optlen)172 int bctbx_getsockopt(bctbx_socket_t sockfd, int level, int optname,
173 						void *optval, socklen_t* optlen){
174 	return pDefaultvSocket->pSocketMethods->pFuncGetSockOpt(sockfd, level, optname, optval, optlen);
175 
176 }
177 
bctbx_setsockopt(bctbx_socket_t sockfd,int level,int optname,const void * optval,socklen_t optlen)178 int bctbx_setsockopt(bctbx_socket_t sockfd, int level, int optname,
179 							const void *optval, socklen_t optlen){
180 	return pDefaultvSocket->pSocketMethods->pFuncSetSockOpt(sockfd, level, optname, optval, optlen);
181 
182 }
183 
184 
bctbx_shutdown(bctbx_socket_t sock,int how)185 int bctbx_shutdown(bctbx_socket_t sock, int how){
186 	return pDefaultvSocket->pSocketMethods->pFuncShutdown(sock, how);
187 }
188 
189 
bctbx_socket_error(int err)190 char* bctbx_socket_error(int err){
191 	return pDefaultvSocket->pSocketMethods->pFuncGetError(err);
192 }
193 
bctbx_vsocket_api_set_default(bctbx_vsocket_api_t * my_vsocket_api)194 void bctbx_vsocket_api_set_default(bctbx_vsocket_api_t *my_vsocket_api) {
195 
196 	if (my_vsocket_api == NULL){
197 		pDefaultvSocket = &bcvSocket;
198 	}
199 	else {
200 		pDefaultvSocket = my_vsocket_api ;
201 	}
202 
203 }
204 
bctbx_vsocket_api_get_default(void)205 bctbx_vsocket_api_t* bctbx_vsocket_api_get_default(void) {
206 	return pDefaultvSocket;
207 }
208 
bctbx_vsocket_api_get_standard(void)209 bctbx_vsocket_api_t* bctbx_vsocket_api_get_standard(void) {
210 	return &bcvSocket;
211 }
212 
213 
214 
215