blob: 67b52a752bea348a051f69f377be14ec6a8e7baa [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * TCP networking functions
3 *
Paul Bakkerfc8c4362010-03-21 17:37:16 +00004 * Copyright (C) 2006-2010, Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakker77b385e2009-07-28 17:23:11 +00005 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00006 *
Paul Bakker5121ce52009-01-03 21:22:43 +00007 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
Paul Bakker40e46942009-01-03 21:51:57 +000022#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000023
Paul Bakker40e46942009-01-03 21:51:57 +000024#if defined(POLARSSL_NET_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000025
Paul Bakker40e46942009-01-03 21:51:57 +000026#include "polarssl/net.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Paul Bakkerff60ee62010-03-16 21:09:09 +000028#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
30#include <winsock2.h>
31#include <windows.h>
32
33#if defined(_WIN32_WCE)
34#pragma comment( lib, "ws2.lib" )
35#else
36#pragma comment( lib, "ws2_32.lib" )
37#endif
38
39#define read(fd,buf,len) recv(fd,buf,len,0)
40#define write(fd,buf,len) send(fd,buf,len,0)
41#define close(fd) closesocket(fd)
42
43static int wsa_init_done = 0;
44
45#else
46
47#include <sys/types.h>
48#include <sys/socket.h>
49#include <netinet/in.h>
50#include <arpa/inet.h>
51#include <sys/time.h>
52#include <unistd.h>
53#include <signal.h>
54#include <fcntl.h>
55#include <netdb.h>
56#include <errno.h>
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000057
Paul Bakker854963c2009-07-19 20:50:11 +000058#if defined(__FreeBSD__)
59#include <sys/endian.h>
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000060#elif defined(__APPLE__)
61#include <machine/endian.h>
Paul Bakker854963c2009-07-19 20:50:11 +000062#else
Paul Bakker1d4f30c2009-04-19 18:55:16 +000063#include <endian.h>
Paul Bakker854963c2009-07-19 20:50:11 +000064#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000065
66#endif
67
68#include <string.h>
69#include <stdlib.h>
70#include <stdio.h>
71#include <time.h>
72
73/*
Paul Bakker1d4f30c2009-04-19 18:55:16 +000074 * htons() is not always available.
75 * By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and __BIG_ENDIAN
76 * to help determine endianess.
Paul Bakker5121ce52009-01-03 21:22:43 +000077 */
Paul Bakker1d4f30c2009-04-19 18:55:16 +000078#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000079#define POLARSSL_HTONS(n) (n)
Paul Bakker1d4f30c2009-04-19 18:55:16 +000080#else
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000081#define POLARSSL_HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
Paul Bakker1d4f30c2009-04-19 18:55:16 +000082#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000083
Paul Bakker1d4f30c2009-04-19 18:55:16 +000084unsigned short net_htons(unsigned short n);
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000085#define net_htons(n) POLARSSL_HTONS(n)
Paul Bakker5121ce52009-01-03 21:22:43 +000086
87/*
88 * Initiate a TCP connection with host:port
89 */
Paul Bakkerff60ee62010-03-16 21:09:09 +000090int net_connect( int *fd, const char *host, int port )
Paul Bakker5121ce52009-01-03 21:22:43 +000091{
92 struct sockaddr_in server_addr;
93 struct hostent *server_host;
94
Paul Bakkerff60ee62010-03-16 21:09:09 +000095#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +000096 WSADATA wsaData;
97
98 if( wsa_init_done == 0 )
99 {
100 if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
Paul Bakker40e46942009-01-03 21:51:57 +0000101 return( POLARSSL_ERR_NET_SOCKET_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000102
103 wsa_init_done = 1;
104 }
105#else
106 signal( SIGPIPE, SIG_IGN );
107#endif
108
109 if( ( server_host = gethostbyname( host ) ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000110 return( POLARSSL_ERR_NET_UNKNOWN_HOST );
Paul Bakker5121ce52009-01-03 21:22:43 +0000111
112 if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000113 return( POLARSSL_ERR_NET_SOCKET_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000114
115 memcpy( (void *) &server_addr.sin_addr,
116 (void *) server_host->h_addr,
117 server_host->h_length );
118
119 server_addr.sin_family = AF_INET;
120 server_addr.sin_port = net_htons( port );
121
122 if( connect( *fd, (struct sockaddr *) &server_addr,
123 sizeof( server_addr ) ) < 0 )
124 {
125 close( *fd );
Paul Bakker40e46942009-01-03 21:51:57 +0000126 return( POLARSSL_ERR_NET_CONNECT_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000127 }
128
129 return( 0 );
130}
131
132/*
133 * Create a listening socket on bind_ip:port
134 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000135int net_bind( int *fd, const char *bind_ip, int port )
Paul Bakker5121ce52009-01-03 21:22:43 +0000136{
137 int n, c[4];
138 struct sockaddr_in server_addr;
139
Paul Bakkerff60ee62010-03-16 21:09:09 +0000140#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000141 WSADATA wsaData;
142
143 if( wsa_init_done == 0 )
144 {
145 if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
Paul Bakker40e46942009-01-03 21:51:57 +0000146 return( POLARSSL_ERR_NET_SOCKET_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000147
148 wsa_init_done = 1;
149 }
150#else
151 signal( SIGPIPE, SIG_IGN );
152#endif
153
154 if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000155 return( POLARSSL_ERR_NET_SOCKET_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000156
157 n = 1;
158 setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR,
159 (const char *) &n, sizeof( n ) );
160
161 server_addr.sin_addr.s_addr = INADDR_ANY;
162 server_addr.sin_family = AF_INET;
163 server_addr.sin_port = net_htons( port );
164
165 if( bind_ip != NULL )
166 {
167 memset( c, 0, sizeof( c ) );
168 sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] );
169
170 for( n = 0; n < 4; n++ )
171 if( c[n] < 0 || c[n] > 255 )
172 break;
173
174 if( n == 4 )
175 server_addr.sin_addr.s_addr =
176 ( (unsigned long) c[0] << 24 ) |
177 ( (unsigned long) c[1] << 16 ) |
178 ( (unsigned long) c[2] << 8 ) |
179 ( (unsigned long) c[3] );
180 }
181
182 if( bind( *fd, (struct sockaddr *) &server_addr,
183 sizeof( server_addr ) ) < 0 )
184 {
185 close( *fd );
Paul Bakker40e46942009-01-03 21:51:57 +0000186 return( POLARSSL_ERR_NET_BIND_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000187 }
188
189 if( listen( *fd, 10 ) != 0 )
190 {
191 close( *fd );
Paul Bakker40e46942009-01-03 21:51:57 +0000192 return( POLARSSL_ERR_NET_LISTEN_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000193 }
194
195 return( 0 );
196}
197
198/*
199 * Check if the current operation is blocking
200 */
201static int net_is_blocking( void )
202{
Paul Bakkerff60ee62010-03-16 21:09:09 +0000203#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000204 return( WSAGetLastError() == WSAEWOULDBLOCK );
205#else
206 switch( errno )
207 {
208#if defined EAGAIN
209 case EAGAIN:
210#endif
211#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
212 case EWOULDBLOCK:
213#endif
214 return( 1 );
215 }
216 return( 0 );
217#endif
218}
219
220/*
221 * Accept a connection from a remote client
222 */
223int net_accept( int bind_fd, int *client_fd, void *client_ip )
224{
225 struct sockaddr_in client_addr;
226
Paul Bakker4ed999c2010-03-16 21:16:16 +0000227#if defined(__socklen_t_defined) || defined(_SOCKLEN_T)
Paul Bakker5121ce52009-01-03 21:22:43 +0000228 socklen_t n = (socklen_t) sizeof( client_addr );
229#else
230 int n = (int) sizeof( client_addr );
231#endif
232
233 *client_fd = accept( bind_fd, (struct sockaddr *)
234 &client_addr, &n );
235
236 if( *client_fd < 0 )
237 {
238 if( net_is_blocking() != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000239 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000240
Paul Bakker40e46942009-01-03 21:51:57 +0000241 return( POLARSSL_ERR_NET_ACCEPT_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000242 }
243
244 if( client_ip != NULL )
245 memcpy( client_ip, &client_addr.sin_addr.s_addr,
246 sizeof( client_addr.sin_addr.s_addr ) );
247
248 return( 0 );
249}
250
251/*
252 * Set the socket blocking or non-blocking
253 */
254int net_set_block( int fd )
255{
Paul Bakkerff60ee62010-03-16 21:09:09 +0000256#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000257 long n = 0;
258 return( ioctlsocket( fd, FIONBIO, &n ) );
259#else
260 return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) );
261#endif
262}
263
264int net_set_nonblock( int fd )
265{
Paul Bakkerff60ee62010-03-16 21:09:09 +0000266#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 long n = 1;
268 return( ioctlsocket( fd, FIONBIO, &n ) );
269#else
270 return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) );
271#endif
272}
273
274/*
275 * Portable usleep helper
276 */
277void net_usleep( unsigned long usec )
278{
279 struct timeval tv;
280 tv.tv_sec = 0;
281 tv.tv_usec = usec;
282 select( 0, NULL, NULL, NULL, &tv );
283}
284
285/*
286 * Read at most 'len' characters
287 */
288int net_recv( void *ctx, unsigned char *buf, int len )
289{
290 int ret = read( *((int *) ctx), buf, len );
291
292 if( len > 0 && ret == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000293 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000294
295 if( ret < 0 )
296 {
297 if( net_is_blocking() != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000298 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
Paul Bakkerff60ee62010-03-16 21:09:09 +0000300#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000301 if( WSAGetLastError() == WSAECONNRESET )
Paul Bakker40e46942009-01-03 21:51:57 +0000302 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303#else
304 if( errno == EPIPE || errno == ECONNRESET )
Paul Bakker40e46942009-01-03 21:51:57 +0000305 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
307 if( errno == EINTR )
Paul Bakker40e46942009-01-03 21:51:57 +0000308 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000309#endif
310
Paul Bakker40e46942009-01-03 21:51:57 +0000311 return( POLARSSL_ERR_NET_RECV_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000312 }
313
314 return( ret );
315}
316
317/*
318 * Write at most 'len' characters
319 */
320int net_send( void *ctx, unsigned char *buf, int len )
321{
322 int ret = write( *((int *) ctx), buf, len );
323
324 if( ret < 0 )
325 {
326 if( net_is_blocking() != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000327 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000328
Paul Bakkerff60ee62010-03-16 21:09:09 +0000329#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 if( WSAGetLastError() == WSAECONNRESET )
Paul Bakker40e46942009-01-03 21:51:57 +0000331 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000332#else
333 if( errno == EPIPE || errno == ECONNRESET )
Paul Bakker40e46942009-01-03 21:51:57 +0000334 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
336 if( errno == EINTR )
Paul Bakker40e46942009-01-03 21:51:57 +0000337 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338#endif
339
Paul Bakker40e46942009-01-03 21:51:57 +0000340 return( POLARSSL_ERR_NET_SEND_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000341 }
342
343 return( ret );
344}
345
346/*
347 * Gracefully close the connection
348 */
349void net_close( int fd )
350{
351 shutdown( fd, 2 );
352 close( fd );
353}
354
355#endif