initial commit; it works
[psslcertgen.git] / src / libpolarssl / net.c
blob500d8b982e6d889c38423f85ea4bd93c67a3a4cd
1 /*
2 * TCP networking functions
4 * Copyright (C) 2006-2010, Brainspark B.V.
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
9 * All rights reserved.
11 * 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.
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.
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.
26 #include "config.h"
28 #if defined(POLARSSL_NET_C)
30 #include "net.h"
32 #if defined(_WIN32) || defined(_WIN32_WCE)
34 #include <winsock2.h>
35 #include <windows.h>
37 #if defined(_WIN32_WCE)
38 #pragma comment( lib, "ws2.lib" )
39 #else
40 #pragma comment( lib, "ws2_32.lib" )
41 #endif
43 #define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0)
44 #define write(fd,buf,len) send(fd,(char*)buf,(int) len,0)
45 #define close(fd) closesocket(fd)
47 static int wsa_init_done = 0;
49 #else
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>
62 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
63 defined(__DragonflyBSD__)
64 #include <sys/endian.h>
65 #elif defined(__APPLE__)
66 #include <machine/endian.h>
67 #elif defined(sun)
68 #include <sys/isa_defs.h>
69 #else
70 #include <endian.h>
71 #endif
73 #endif
75 #include <stdlib.h>
76 #include <stdio.h>
77 #include <time.h>
79 #ifdef _MSC_VER
80 #include <basetsd.h>
81 typedef UINT32 uint32_t;
82 #else
83 #include <inttypes.h>
84 #endif
87 * htons() is not always available.
88 * By default go for LITTLE_ENDIAN variant. Otherwise hope for _BYTE_ORDER and __BIG_ENDIAN
89 * to help determine endianess.
91 #if defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN
92 #define POLARSSL_HTONS(n) (n)
93 #define POLARSSL_HTONL(n) (n)
94 #else
95 #define POLARSSL_HTONS(n) ((((unsigned short)(n) & 0xFF ) << 8 ) | \
96 (((unsigned short)(n) & 0xFF00 ) >> 8 ))
97 #define POLARSSL_HTONL(n) ((((unsigned long )(n) & 0xFF ) << 24) | \
98 (((unsigned long )(n) & 0xFF00 ) << 8 ) | \
99 (((unsigned long )(n) & 0xFF0000 ) >> 8 ) | \
100 (((unsigned long )(n) & 0xFF000000) >> 24))
101 #endif
103 unsigned short pssl_net_htons(unsigned short n);
104 unsigned long pssl_net_htonl(unsigned long n);
105 #define pssl_net_htons(n) POLARSSL_HTONS(n)
106 #define pssl_net_htonl(n) POLARSSL_HTONL(n)
109 * Initiate a TCP connection with host:port
111 int pssl_net_connect( int *fd, const char *host, int port )
113 struct sockaddr_in server_addr;
114 struct hostent *server_host;
116 #if defined(_WIN32) || defined(_WIN32_WCE)
117 WSADATA wsaData;
119 if( wsa_init_done == 0 )
121 if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
122 return( POLARSSL_ERR_NET_SOCKET_FAILED );
124 wsa_init_done = 1;
126 #else
127 signal( SIGPIPE, SIG_IGN );
128 #endif
130 if( ( server_host = gethostbyname( host ) ) == NULL )
131 return( POLARSSL_ERR_NET_UNKNOWN_HOST );
133 if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
134 return( POLARSSL_ERR_NET_SOCKET_FAILED );
136 memcpy( (void *) &server_addr.sin_addr,
137 (void *) server_host->h_addr,
138 server_host->h_length );
140 server_addr.sin_family = AF_INET;
141 server_addr.sin_port = pssl_net_htons( port );
143 if( connect( *fd, (struct sockaddr *) &server_addr,
144 sizeof( server_addr ) ) < 0 )
146 close( *fd );
147 return( POLARSSL_ERR_NET_CONNECT_FAILED );
150 return( 0 );
154 * Create a listening socket on bind_ip:port
156 int pssl_net_bind( int *fd, const char *bind_ip, int port )
158 int n, c[4];
159 struct sockaddr_in server_addr;
161 #if defined(_WIN32) || defined(_WIN32_WCE)
162 WSADATA wsaData;
164 if( wsa_init_done == 0 )
166 if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
167 return( POLARSSL_ERR_NET_SOCKET_FAILED );
169 wsa_init_done = 1;
171 #else
172 signal( SIGPIPE, SIG_IGN );
173 #endif
175 if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
176 return( POLARSSL_ERR_NET_SOCKET_FAILED );
178 n = 1;
179 setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR,
180 (const char *) &n, sizeof( n ) );
182 server_addr.sin_addr.s_addr = pssl_net_htonl( INADDR_ANY );
183 server_addr.sin_family = AF_INET;
184 server_addr.sin_port = pssl_net_htons( port );
186 if( bind_ip != NULL )
188 memset( c, 0, sizeof( c ) );
189 sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] );
191 for( n = 0; n < 4; n++ )
192 if( c[n] < 0 || c[n] > 255 )
193 break;
195 if( n == 4 )
196 server_addr.sin_addr.s_addr = pssl_net_htonl(
197 ( (uint32_t) c[0] << 24 ) |
198 ( (uint32_t) c[1] << 16 ) |
199 ( (uint32_t) c[2] << 8 ) |
200 ( (uint32_t) c[3] ) );
203 if( bind( *fd, (struct sockaddr *) &server_addr,
204 sizeof( server_addr ) ) < 0 )
206 close( *fd );
207 return( POLARSSL_ERR_NET_BIND_FAILED );
210 if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 )
212 close( *fd );
213 return( POLARSSL_ERR_NET_LISTEN_FAILED );
216 return( 0 );
220 * Check if the current operation is blocking
222 static int pssl_net_is_blocking( void )
224 #if defined(_WIN32) || defined(_WIN32_WCE)
225 return( WSAGetLastError() == WSAEWOULDBLOCK );
226 #else
227 switch( errno )
229 #if defined EAGAIN
230 case EAGAIN:
231 #endif
232 #if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
233 case EWOULDBLOCK:
234 #endif
235 return( 1 );
237 return( 0 );
238 #endif
242 * Accept a connection from a remote client
244 int pssl_net_accept( int bind_fd, int *client_fd, void *client_ip )
246 struct sockaddr_in client_addr;
248 #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
249 defined(_SOCKLEN_T_DECLARED)
250 socklen_t n = (socklen_t) sizeof( client_addr );
251 #else
252 int n = (int) sizeof( client_addr );
253 #endif
255 *client_fd = accept( bind_fd, (struct sockaddr *)
256 &client_addr, &n );
258 if( *client_fd < 0 )
260 if( pssl_net_is_blocking() != 0 )
261 return( POLARSSL_ERR_NET_WANT_READ );
263 return( POLARSSL_ERR_NET_ACCEPT_FAILED );
266 if( client_ip != NULL )
267 memcpy( client_ip, &client_addr.sin_addr.s_addr,
268 sizeof( client_addr.sin_addr.s_addr ) );
270 return( 0 );
274 * Set the socket blocking or non-blocking
276 int pssl_net_set_block( int fd )
278 #if defined(_WIN32) || defined(_WIN32_WCE)
279 u_long n = 0;
280 return( ioctlsocket( fd, FIONBIO, &n ) );
281 #else
282 return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) );
283 #endif
286 int pssl_net_set_nonblock( int fd )
288 #if defined(_WIN32) || defined(_WIN32_WCE)
289 u_long n = 1;
290 return( ioctlsocket( fd, FIONBIO, &n ) );
291 #else
292 return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) );
293 #endif
297 * Portable usleep helper
299 void pssl_net_usleep( unsigned long usec )
301 struct timeval tv;
302 tv.tv_sec = 0;
303 tv.tv_usec = usec;
304 select( 0, NULL, NULL, NULL, &tv );
308 * Read at most 'len' characters
310 int pssl_net_recv( void *ctx, unsigned char *buf, size_t len )
312 int ret = read( *((int *) ctx), buf, len );
314 if( ret < 0 )
316 if( pssl_net_is_blocking() != 0 )
317 return( POLARSSL_ERR_NET_WANT_READ );
319 #if defined(_WIN32) || defined(_WIN32_WCE)
320 if( WSAGetLastError() == WSAECONNRESET )
321 return( POLARSSL_ERR_NET_CONN_RESET );
322 #else
323 if( errno == EPIPE || errno == ECONNRESET )
324 return( POLARSSL_ERR_NET_CONN_RESET );
326 if( errno == EINTR )
327 return( POLARSSL_ERR_NET_WANT_READ );
328 #endif
330 return( POLARSSL_ERR_NET_RECV_FAILED );
333 return( ret );
337 * Write at most 'len' characters
339 int pssl_net_send( void *ctx, const unsigned char *buf, size_t len )
341 int ret = write( *((int *) ctx), buf, len );
343 if( ret < 0 )
345 if( pssl_net_is_blocking() != 0 )
346 return( POLARSSL_ERR_NET_WANT_WRITE );
348 #if defined(_WIN32) || defined(_WIN32_WCE)
349 if( WSAGetLastError() == WSAECONNRESET )
350 return( POLARSSL_ERR_NET_CONN_RESET );
351 #else
352 if( errno == EPIPE || errno == ECONNRESET )
353 return( POLARSSL_ERR_NET_CONN_RESET );
355 if( errno == EINTR )
356 return( POLARSSL_ERR_NET_WANT_WRITE );
357 #endif
359 return( POLARSSL_ERR_NET_SEND_FAILED );
362 return( ret );
366 * Gracefully close the connection
368 void pssl_net_close( int fd )
370 shutdown( fd, 2 );
371 close( fd );
374 #endif