blob: e884d56fc82259e7947b0ac6adae8774f58ddad2 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * TCP networking functions
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
Paul Bakker40e46942009-01-03 21:51:57 +000026#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Paul Bakker40e46942009-01-03 21:51:57 +000028#if defined(POLARSSL_NET_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Paul Bakker40e46942009-01-03 21:51:57 +000030#include "polarssl/net.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Paul Bakkerff60ee62010-03-16 21:09:09 +000032#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +000033
34#include <winsock2.h>
35#include <windows.h>
36
37#if defined(_WIN32_WCE)
38#pragma comment( lib, "ws2.lib" )
39#else
40#pragma comment( lib, "ws2_32.lib" )
41#endif
42
43#define read(fd,buf,len) recv(fd,buf,len,0)
44#define write(fd,buf,len) send(fd,buf,len,0)
45#define close(fd) closesocket(fd)
46
47static int wsa_init_done = 0;
48
49#else
50
51#include <sys/types.h>
52#include <sys/socket.h>
53#include <netinet/in.h>
54#include <arpa/inet.h>
55#include <sys/time.h>
56#include <unistd.h>
57#include <signal.h>
58#include <fcntl.h>
59#include <netdb.h>
60#include <errno.h>
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000061
Paul Bakker854963c2009-07-19 20:50:11 +000062#if defined(__FreeBSD__)
63#include <sys/endian.h>
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000064#elif defined(__APPLE__)
65#include <machine/endian.h>
Paul Bakker854963c2009-07-19 20:50:11 +000066#else
Paul Bakker1d4f30c2009-04-19 18:55:16 +000067#include <endian.h>
Paul Bakker854963c2009-07-19 20:50:11 +000068#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000069
70#endif
71
72#include <string.h>
73#include <stdlib.h>
74#include <stdio.h>
75#include <time.h>
76
77/*
Paul Bakker1d4f30c2009-04-19 18:55:16 +000078 * htons() is not always available.
79 * By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and __BIG_ENDIAN
80 * to help determine endianess.
Paul Bakker5121ce52009-01-03 21:22:43 +000081 */
Paul Bakker1d4f30c2009-04-19 18:55:16 +000082#if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000083#define POLARSSL_HTONS(n) (n)
Paul Bakker1d4f30c2009-04-19 18:55:16 +000084#else
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000085#define POLARSSL_HTONS(n) (((((unsigned short)(n) & 0xFF)) << 8) | (((unsigned short)(n) & 0xFF00) >> 8))
Paul Bakker1d4f30c2009-04-19 18:55:16 +000086#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000087
Paul Bakker1d4f30c2009-04-19 18:55:16 +000088unsigned short net_htons(unsigned short n);
Paul Bakkerb3bb6c02009-07-27 21:09:47 +000089#define net_htons(n) POLARSSL_HTONS(n)
Paul Bakker5121ce52009-01-03 21:22:43 +000090
91/*
92 * Initiate a TCP connection with host:port
93 */
Paul Bakkerff60ee62010-03-16 21:09:09 +000094int net_connect( int *fd, const char *host, int port )
Paul Bakker5121ce52009-01-03 21:22:43 +000095{
96 struct sockaddr_in server_addr;
97 struct hostent *server_host;
98
Paul Bakkerff60ee62010-03-16 21:09:09 +000099#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000100 WSADATA wsaData;
101
102 if( wsa_init_done == 0 )
103 {
104 if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
Paul Bakker40e46942009-01-03 21:51:57 +0000105 return( POLARSSL_ERR_NET_SOCKET_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000106
107 wsa_init_done = 1;
108 }
109#else
110 signal( SIGPIPE, SIG_IGN );
111#endif
112
113 if( ( server_host = gethostbyname( host ) ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000114 return( POLARSSL_ERR_NET_UNKNOWN_HOST );
Paul Bakker5121ce52009-01-03 21:22:43 +0000115
116 if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000117 return( POLARSSL_ERR_NET_SOCKET_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000118
119 memcpy( (void *) &server_addr.sin_addr,
120 (void *) server_host->h_addr,
121 server_host->h_length );
122
123 server_addr.sin_family = AF_INET;
124 server_addr.sin_port = net_htons( port );
125
126 if( connect( *fd, (struct sockaddr *) &server_addr,
127 sizeof( server_addr ) ) < 0 )
128 {
129 close( *fd );
Paul Bakker40e46942009-01-03 21:51:57 +0000130 return( POLARSSL_ERR_NET_CONNECT_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000131 }
132
133 return( 0 );
134}
135
136/*
137 * Create a listening socket on bind_ip:port
138 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000139int net_bind( int *fd, const char *bind_ip, int port )
Paul Bakker5121ce52009-01-03 21:22:43 +0000140{
141 int n, c[4];
142 struct sockaddr_in server_addr;
143
Paul Bakkerff60ee62010-03-16 21:09:09 +0000144#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000145 WSADATA wsaData;
146
147 if( wsa_init_done == 0 )
148 {
149 if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
Paul Bakker40e46942009-01-03 21:51:57 +0000150 return( POLARSSL_ERR_NET_SOCKET_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
152 wsa_init_done = 1;
153 }
154#else
155 signal( SIGPIPE, SIG_IGN );
156#endif
157
158 if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000159 return( POLARSSL_ERR_NET_SOCKET_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000160
161 n = 1;
162 setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR,
163 (const char *) &n, sizeof( n ) );
164
165 server_addr.sin_addr.s_addr = INADDR_ANY;
166 server_addr.sin_family = AF_INET;
167 server_addr.sin_port = net_htons( port );
168
169 if( bind_ip != NULL )
170 {
171 memset( c, 0, sizeof( c ) );
172 sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] );
173
174 for( n = 0; n < 4; n++ )
175 if( c[n] < 0 || c[n] > 255 )
176 break;
177
178 if( n == 4 )
179 server_addr.sin_addr.s_addr =
180 ( (unsigned long) c[0] << 24 ) |
181 ( (unsigned long) c[1] << 16 ) |
182 ( (unsigned long) c[2] << 8 ) |
183 ( (unsigned long) c[3] );
184 }
185
186 if( bind( *fd, (struct sockaddr *) &server_addr,
187 sizeof( server_addr ) ) < 0 )
188 {
189 close( *fd );
Paul Bakker40e46942009-01-03 21:51:57 +0000190 return( POLARSSL_ERR_NET_BIND_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000191 }
192
193 if( listen( *fd, 10 ) != 0 )
194 {
195 close( *fd );
Paul Bakker40e46942009-01-03 21:51:57 +0000196 return( POLARSSL_ERR_NET_LISTEN_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000197 }
198
199 return( 0 );
200}
201
202/*
203 * Check if the current operation is blocking
204 */
205static int net_is_blocking( void )
206{
Paul Bakkerff60ee62010-03-16 21:09:09 +0000207#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000208 return( WSAGetLastError() == WSAEWOULDBLOCK );
209#else
210 switch( errno )
211 {
212#if defined EAGAIN
213 case EAGAIN:
214#endif
215#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
216 case EWOULDBLOCK:
217#endif
218 return( 1 );
219 }
220 return( 0 );
221#endif
222}
223
224/*
225 * Accept a connection from a remote client
226 */
227int net_accept( int bind_fd, int *client_fd, void *client_ip )
228{
229 struct sockaddr_in client_addr;
230
Paul Bakker4ed999c2010-03-16 21:16:16 +0000231#if defined(__socklen_t_defined) || defined(_SOCKLEN_T)
Paul Bakker5121ce52009-01-03 21:22:43 +0000232 socklen_t n = (socklen_t) sizeof( client_addr );
233#else
234 int n = (int) sizeof( client_addr );
235#endif
236
237 *client_fd = accept( bind_fd, (struct sockaddr *)
238 &client_addr, &n );
239
240 if( *client_fd < 0 )
241 {
242 if( net_is_blocking() != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000243 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000244
Paul Bakker40e46942009-01-03 21:51:57 +0000245 return( POLARSSL_ERR_NET_ACCEPT_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000246 }
247
248 if( client_ip != NULL )
249 memcpy( client_ip, &client_addr.sin_addr.s_addr,
250 sizeof( client_addr.sin_addr.s_addr ) );
251
252 return( 0 );
253}
254
255/*
256 * Set the socket blocking or non-blocking
257 */
258int net_set_block( int fd )
259{
Paul Bakkerff60ee62010-03-16 21:09:09 +0000260#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000261 long n = 0;
262 return( ioctlsocket( fd, FIONBIO, &n ) );
263#else
264 return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) );
265#endif
266}
267
268int net_set_nonblock( int fd )
269{
Paul Bakkerff60ee62010-03-16 21:09:09 +0000270#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 long n = 1;
272 return( ioctlsocket( fd, FIONBIO, &n ) );
273#else
274 return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) );
275#endif
276}
277
278/*
279 * Portable usleep helper
280 */
281void net_usleep( unsigned long usec )
282{
283 struct timeval tv;
284 tv.tv_sec = 0;
285 tv.tv_usec = usec;
286 select( 0, NULL, NULL, NULL, &tv );
287}
288
289/*
290 * Read at most 'len' characters
291 */
292int net_recv( void *ctx, unsigned char *buf, int len )
293{
294 int ret = read( *((int *) ctx), buf, len );
295
296 if( len > 0 && ret == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000297 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
299 if( ret < 0 )
300 {
301 if( net_is_blocking() != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000302 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
Paul Bakkerff60ee62010-03-16 21:09:09 +0000304#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000305 if( WSAGetLastError() == WSAECONNRESET )
Paul Bakker40e46942009-01-03 21:51:57 +0000306 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307#else
308 if( errno == EPIPE || errno == ECONNRESET )
Paul Bakker40e46942009-01-03 21:51:57 +0000309 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
311 if( errno == EINTR )
Paul Bakker40e46942009-01-03 21:51:57 +0000312 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313#endif
314
Paul Bakker40e46942009-01-03 21:51:57 +0000315 return( POLARSSL_ERR_NET_RECV_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000316 }
317
318 return( ret );
319}
320
321/*
322 * Write at most 'len' characters
323 */
324int net_send( void *ctx, unsigned char *buf, int len )
325{
326 int ret = write( *((int *) ctx), buf, len );
327
328 if( ret < 0 )
329 {
330 if( net_is_blocking() != 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000331 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
Paul Bakkerff60ee62010-03-16 21:09:09 +0000333#if defined(_WIN32) || defined(_WIN32_WCE)
Paul Bakker5121ce52009-01-03 21:22:43 +0000334 if( WSAGetLastError() == WSAECONNRESET )
Paul Bakker40e46942009-01-03 21:51:57 +0000335 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000336#else
337 if( errno == EPIPE || errno == ECONNRESET )
Paul Bakker40e46942009-01-03 21:51:57 +0000338 return( POLARSSL_ERR_NET_CONN_RESET );
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
340 if( errno == EINTR )
Paul Bakker40e46942009-01-03 21:51:57 +0000341 return( POLARSSL_ERR_NET_TRY_AGAIN );
Paul Bakker5121ce52009-01-03 21:22:43 +0000342#endif
343
Paul Bakker40e46942009-01-03 21:51:57 +0000344 return( POLARSSL_ERR_NET_SEND_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000345 }
346
347 return( ret );
348}
349
350/*
351 * Gracefully close the connection
352 */
353void net_close( int fd )
354{
355 shutdown( fd, 2 );
356 close( fd );
357}
358
359#endif