PolarSSL v1.2.12
net.c
Go to the documentation of this file.
1 /*
2  * TCP networking functions
3  *
4  * Copyright (C) 2006-2010, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
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.
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 
26 #include "polarssl/config.h"
27 
28 #if defined(POLARSSL_NET_C)
29 
30 #include "polarssl/net.h"
31 
32 #if defined(_WIN32) || defined(_WIN32_WCE)
33 
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,(char*)buf,(int) len,0)
44 #define write(fd,buf,len) send(fd,(char*)buf,(int) len,0)
45 #define close(fd) closesocket(fd)
46 
47 static 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>
61 
62 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
63  defined(__DragonFly__)
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
72 
73 #endif
74 
75 #include <stdlib.h>
76 #include <stdio.h>
77 #include <time.h>
78 
79 #ifdef _MSC_VER
80 #include <basetsd.h>
81 typedef UINT32 uint32_t;
82 #else
83 #include <inttypes.h>
84 #endif
85 
86 /*
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.
90  */
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
102 
103 unsigned short net_htons(unsigned short n);
104 unsigned long net_htonl(unsigned long n);
105 #define net_htons(n) POLARSSL_HTONS(n)
106 #define net_htonl(n) POLARSSL_HTONL(n)
107 
108 /*
109  * Initiate a TCP connection with host:port
110  */
111 int net_connect( int *fd, const char *host, int port )
112 {
113  struct sockaddr_in server_addr;
114  struct hostent *server_host;
115 
116 #if defined(_WIN32) || defined(_WIN32_WCE)
117  WSADATA wsaData;
118 
119  if( wsa_init_done == 0 )
120  {
121  if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
123 
124  wsa_init_done = 1;
125  }
126 #else
127  signal( SIGPIPE, SIG_IGN );
128 #endif
129 
130  memset( &server_addr, 0, sizeof( server_addr ) );
131 
132  if( ( server_host = gethostbyname( host ) ) == NULL )
134 
135  if( ( *fd = (int) socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
137 
138  memcpy( (void *) &server_addr.sin_addr,
139  (void *) server_host->h_addr,
140  server_host->h_length );
141 
142  server_addr.sin_family = AF_INET;
143  server_addr.sin_port = net_htons( port );
144 
145  if( connect( *fd, (struct sockaddr *) &server_addr,
146  sizeof( server_addr ) ) < 0 )
147  {
148  close( *fd );
150  }
151 
152  return( 0 );
153 }
154 
155 /*
156  * Create a listening socket on bind_ip:port
157  */
158 int net_bind( int *fd, const char *bind_ip, int port )
159 {
160  int n, c[4];
161  struct sockaddr_in server_addr;
162 
163 #if defined(_WIN32) || defined(_WIN32_WCE)
164  WSADATA wsaData;
165 
166  if( wsa_init_done == 0 )
167  {
168  if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR )
170 
171  wsa_init_done = 1;
172  }
173 #else
174  signal( SIGPIPE, SIG_IGN );
175 #endif
176 
177  memset( &server_addr, 0, sizeof( server_addr ) );
178 
179  if( ( *fd = (int) socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 )
181 
182  n = 1;
183  if( setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR,
184  (const char *) &n, sizeof( n ) ) != 0 )
185  {
186  close( *fd );
188  }
189 
190  server_addr.sin_addr.s_addr = net_htonl( INADDR_ANY );
191  server_addr.sin_family = AF_INET;
192  server_addr.sin_port = net_htons( port );
193 
194  if( bind_ip != NULL )
195  {
196  memset( c, 0, sizeof( c ) );
197  sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] );
198 
199  for( n = 0; n < 4; n++ )
200  if( c[n] < 0 || c[n] > 255 )
201  break;
202 
203  if( n == 4 )
204  server_addr.sin_addr.s_addr = net_htonl(
205  ( (uint32_t) c[0] << 24 ) |
206  ( (uint32_t) c[1] << 16 ) |
207  ( (uint32_t) c[2] << 8 ) |
208  ( (uint32_t) c[3] ) );
209  }
210 
211  if( bind( *fd, (struct sockaddr *) &server_addr,
212  sizeof( server_addr ) ) < 0 )
213  {
214  close( *fd );
216  }
217 
218  if( listen( *fd, POLARSSL_NET_LISTEN_BACKLOG ) != 0 )
219  {
220  close( *fd );
222  }
223 
224  return( 0 );
225 }
226 
227 #if ( defined(_WIN32) || defined(_WIN32_WCE) )
228 /*
229  * Check if the requested operation would be blocking on a non-blocking socket
230  * and thus 'failed' with a negative return value.
231  */
232 static int net_would_block( int fd )
233 {
234  ((void) fd);
235  return( WSAGetLastError() == WSAEWOULDBLOCK );
236 }
237 #else
238 /*
239  * Check if the requested operation would be blocking on a non-blocking socket
240  * and thus 'failed' with a negative return value.
241  *
242  * Note: on a blocking socket this function always returns 0!
243  */
244 static int net_would_block( int fd )
245 {
246  /*
247  * Never return 'WOULD BLOCK' on a non-blocking socket
248  */
249  if( ( fcntl( fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
250  return( 0 );
251 
252  switch( errno )
253  {
254 #if defined EAGAIN
255  case EAGAIN:
256 #endif
257 #if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
258  case EWOULDBLOCK:
259 #endif
260  return( 1 );
261  }
262  return( 0 );
263 }
264 #endif
265 
266 /*
267  * Accept a connection from a remote client
268  */
269 int net_accept( int bind_fd, int *client_fd, void *client_ip )
270 {
271  struct sockaddr_in client_addr;
272 
273 #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
274  defined(_SOCKLEN_T_DECLARED)
275  socklen_t n = (socklen_t) sizeof( client_addr );
276 #else
277  int n = (int) sizeof( client_addr );
278 #endif
279 
280  *client_fd = (int) accept( bind_fd, (struct sockaddr *)
281  &client_addr, &n );
282 
283  if( *client_fd < 0 )
284  {
285  if( net_would_block( bind_fd ) != 0 )
286  return( POLARSSL_ERR_NET_WANT_READ );
287 
289  }
290 
291  if( client_ip != NULL )
292  memcpy( client_ip, &client_addr.sin_addr.s_addr,
293  sizeof( client_addr.sin_addr.s_addr ) );
294 
295  return( 0 );
296 }
297 
298 /*
299  * Set the socket blocking or non-blocking
300  */
301 int net_set_block( int fd )
302 {
303 #if defined(_WIN32) || defined(_WIN32_WCE)
304  u_long n = 0;
305  return( ioctlsocket( fd, FIONBIO, &n ) );
306 #else
307  return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) );
308 #endif
309 }
310 
311 int net_set_nonblock( int fd )
312 {
313 #if defined(_WIN32) || defined(_WIN32_WCE)
314  u_long n = 1;
315  return( ioctlsocket( fd, FIONBIO, &n ) );
316 #else
317  return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) );
318 #endif
319 }
320 
321 /*
322  * Portable usleep helper
323  */
324 void net_usleep( unsigned long usec )
325 {
326  struct timeval tv;
327  tv.tv_sec = 0;
328 #if !defined(_WIN32) && (defined(__unix__) || defined(__unix) || \
329  (defined(__APPLE__) && defined(__MACH__)))
330  tv.tv_usec = (suseconds_t) usec;
331 #else
332  tv.tv_usec = usec;
333 #endif
334  select( 0, NULL, NULL, NULL, &tv );
335 }
336 
337 /*
338  * Read at most 'len' characters
339  */
340 int net_recv( void *ctx, unsigned char *buf, size_t len )
341 {
342  int fd = *((int *) ctx);
343  int ret = (int) read( fd, buf, len );
344 
345  if( ret < 0 )
346  {
347  if( net_would_block( fd ) != 0 )
348  return( POLARSSL_ERR_NET_WANT_READ );
349 
350 #if defined(_WIN32) || defined(_WIN32_WCE)
351  if( WSAGetLastError() == WSAECONNRESET )
352  return( POLARSSL_ERR_NET_CONN_RESET );
353 #else
354  if( errno == EPIPE || errno == ECONNRESET )
355  return( POLARSSL_ERR_NET_CONN_RESET );
356 
357  if( errno == EINTR )
358  return( POLARSSL_ERR_NET_WANT_READ );
359 #endif
360 
362  }
363 
364  return( ret );
365 }
366 
367 /*
368  * Write at most 'len' characters
369  */
370 int net_send( void *ctx, const unsigned char *buf, size_t len )
371 {
372  int fd = *((int *) ctx);
373  int ret = (int) write( fd, buf, len );
374 
375  if( ret < 0 )
376  {
377  if( net_would_block( fd ) != 0 )
378  return( POLARSSL_ERR_NET_WANT_WRITE );
379 
380 #if defined(_WIN32) || defined(_WIN32_WCE)
381  if( WSAGetLastError() == WSAECONNRESET )
382  return( POLARSSL_ERR_NET_CONN_RESET );
383 #else
384  if( errno == EPIPE || errno == ECONNRESET )
385  return( POLARSSL_ERR_NET_CONN_RESET );
386 
387  if( errno == EINTR )
388  return( POLARSSL_ERR_NET_WANT_WRITE );
389 #endif
390 
392  }
393 
394  return( ret );
395 }
396 
397 /*
398  * Gracefully close the connection
399  */
400 void net_close( int fd )
401 {
402  shutdown( fd, 2 );
403  close( fd );
404 }
405 
406 #endif