00001 /* 00002 * TCP networking functions 00003 * 00004 * Copyright (C) 2006-2007 Christophe Devine 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 00021 #include "xyssl/config.h" 00022 00023 #if defined(XYSSL_NET_C) 00024 00025 #include "xyssl/net.h" 00026 00027 #if defined(WIN32) || defined(_WIN32_WCE) 00028 00029 #include <winsock2.h> 00030 #include <windows.h> 00031 00032 #if defined(_WIN32_WCE) 00033 #pragma comment( lib, "ws2.lib" ) 00034 #else 00035 #pragma comment( lib, "ws2_32.lib" ) 00036 #endif 00037 00038 #define read(fd,buf,len) recv(fd,buf,len,0) 00039 #define write(fd,buf,len) send(fd,buf,len,0) 00040 #define close(fd) closesocket(fd) 00041 00042 static int wsa_init_done = 0; 00043 00044 #else 00045 00046 #include <sys/types.h> 00047 #include <sys/socket.h> 00048 #include <netinet/in.h> 00049 #include <arpa/inet.h> 00050 #include <sys/time.h> 00051 #include <unistd.h> 00052 #include <signal.h> 00053 #include <fcntl.h> 00054 #include <netdb.h> 00055 #include <errno.h> 00056 00057 #endif 00058 00059 #include <string.h> 00060 #include <stdlib.h> 00061 #include <stdio.h> 00062 #include <time.h> 00063 00064 /* 00065 * htons() is not always available 00066 */ 00067 static unsigned short net_htons( int port ) 00068 { 00069 unsigned char buf[4]; 00070 00071 buf[0] = (unsigned char)( port >> 8 ); 00072 buf[1] = (unsigned char)( port ); 00073 buf[2] = buf[3] = 0; 00074 00075 return( *(unsigned short *) buf ); 00076 } 00077 00078 /* 00079 * Initiate a TCP connection with host:port 00080 */ 00081 int net_connect( int *fd, char *host, int port ) 00082 { 00083 struct sockaddr_in server_addr; 00084 struct hostent *server_host; 00085 00086 #if defined(WIN32) || defined(_WIN32_WCE) 00087 WSADATA wsaData; 00088 00089 if( wsa_init_done == 0 ) 00090 { 00091 if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR ) 00092 return( XYSSL_ERR_NET_SOCKET_FAILED ); 00093 00094 wsa_init_done = 1; 00095 } 00096 #else 00097 signal( SIGPIPE, SIG_IGN ); 00098 #endif 00099 00100 if( ( server_host = gethostbyname( host ) ) == NULL ) 00101 return( XYSSL_ERR_NET_UNKNOWN_HOST ); 00102 00103 if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 ) 00104 return( XYSSL_ERR_NET_SOCKET_FAILED ); 00105 00106 memcpy( (void *) &server_addr.sin_addr, 00107 (void *) server_host->h_addr, 00108 server_host->h_length ); 00109 00110 server_addr.sin_family = AF_INET; 00111 server_addr.sin_port = net_htons( port ); 00112 00113 if( connect( *fd, (struct sockaddr *) &server_addr, 00114 sizeof( server_addr ) ) < 0 ) 00115 { 00116 close( *fd ); 00117 return( XYSSL_ERR_NET_CONNECT_FAILED ); 00118 } 00119 00120 return( 0 ); 00121 } 00122 00123 /* 00124 * Create a listening socket on bind_ip:port 00125 */ 00126 int net_bind( int *fd, char *bind_ip, int port ) 00127 { 00128 int n, c[4]; 00129 struct sockaddr_in server_addr; 00130 00131 #if defined(WIN32) || defined(_WIN32_WCE) 00132 WSADATA wsaData; 00133 00134 if( wsa_init_done == 0 ) 00135 { 00136 if( WSAStartup( MAKEWORD(2,0), &wsaData ) == SOCKET_ERROR ) 00137 return( XYSSL_ERR_NET_SOCKET_FAILED ); 00138 00139 wsa_init_done = 1; 00140 } 00141 #else 00142 signal( SIGPIPE, SIG_IGN ); 00143 #endif 00144 00145 if( ( *fd = socket( AF_INET, SOCK_STREAM, IPPROTO_IP ) ) < 0 ) 00146 return( XYSSL_ERR_NET_SOCKET_FAILED ); 00147 00148 n = 1; 00149 setsockopt( *fd, SOL_SOCKET, SO_REUSEADDR, 00150 (const char *) &n, sizeof( n ) ); 00151 00152 server_addr.sin_addr.s_addr = INADDR_ANY; 00153 server_addr.sin_family = AF_INET; 00154 server_addr.sin_port = net_htons( port ); 00155 00156 if( bind_ip != NULL ) 00157 { 00158 memset( c, 0, sizeof( c ) ); 00159 sscanf( bind_ip, "%d.%d.%d.%d", &c[0], &c[1], &c[2], &c[3] ); 00160 00161 for( n = 0; n < 4; n++ ) 00162 if( c[n] < 0 || c[n] > 255 ) 00163 break; 00164 00165 if( n == 4 ) 00166 server_addr.sin_addr.s_addr = 00167 ( c[0] << 24 ) | ( c[1] << 16 ) | 00168 ( c[2] << 8 ) | ( c[3] ); 00169 } 00170 00171 if( bind( *fd, (struct sockaddr *) &server_addr, 00172 sizeof( server_addr ) ) < 0 ) 00173 { 00174 close( *fd ); 00175 return( XYSSL_ERR_NET_BIND_FAILED ); 00176 } 00177 00178 if( listen( *fd, 10 ) != 0 ) 00179 { 00180 close( *fd ); 00181 return( XYSSL_ERR_NET_LISTEN_FAILED ); 00182 } 00183 00184 return( 0 ); 00185 } 00186 00187 /* 00188 * Check if the current operation is blocking 00189 */ 00190 static int net_is_blocking( void ) 00191 { 00192 #if defined(WIN32) || defined(_WIN32_WCE) 00193 return( WSAGetLastError() == WSAEWOULDBLOCK ); 00194 #else 00195 switch( errno ) 00196 { 00197 #if defined EAGAIN 00198 case EAGAIN: 00199 #endif 00200 #if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN 00201 case EWOULDBLOCK: 00202 #endif 00203 return( 1 ); 00204 } 00205 return( 0 ); 00206 #endif 00207 } 00208 00209 /* 00210 * Accept a connection from a remote client 00211 */ 00212 int net_accept( int bind_fd, int *client_fd, void *client_ip ) 00213 { 00214 struct sockaddr_in client_addr; 00215 00216 #if defined(__socklen_t_defined) 00217 socklen_t n = (socklen_t) sizeof( client_addr ); 00218 #else 00219 int n = (int) sizeof( client_addr ); 00220 #endif 00221 00222 *client_fd = accept( bind_fd, (struct sockaddr *) 00223 &client_addr, &n ); 00224 00225 if( *client_fd < 0 ) 00226 { 00227 if( net_is_blocking() != 0 ) 00228 return( XYSSL_ERR_NET_TRY_AGAIN ); 00229 00230 return( XYSSL_ERR_NET_ACCEPT_FAILED ); 00231 } 00232 00233 if( client_ip != NULL ) 00234 memcpy( client_ip, &client_addr.sin_addr.s_addr, 00235 sizeof( client_addr.sin_addr.s_addr ) ); 00236 00237 return( 0 ); 00238 } 00239 00240 /* 00241 * Set the socket blocking or non-blocking 00242 */ 00243 int net_set_block( int fd ) 00244 { 00245 #if defined(WIN32) || defined(_WIN32_WCE) 00246 long n = 0; 00247 return( ioctlsocket( fd, FIONBIO, &n ) ); 00248 #else 00249 return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) & ~O_NONBLOCK ) ); 00250 #endif 00251 } 00252 00253 int net_set_nonblock( int fd ) 00254 { 00255 #if defined(WIN32) || defined(_WIN32_WCE) 00256 long n = 1; 00257 return( ioctlsocket( fd, FIONBIO, &n ) ); 00258 #else 00259 return( fcntl( fd, F_SETFL, fcntl( fd, F_GETFL ) | O_NONBLOCK ) ); 00260 #endif 00261 } 00262 00263 /* 00264 * Portable usleep helper 00265 */ 00266 void net_usleep( unsigned long usec ) 00267 { 00268 struct timeval tv; 00269 tv.tv_sec = 0; 00270 tv.tv_usec = usec; 00271 select( 0, NULL, NULL, NULL, &tv ); 00272 } 00273 00274 /* 00275 * Read at most 'len' characters 00276 */ 00277 int net_recv( void *ctx, unsigned char *buf, int len ) 00278 { 00279 int ret = read( *((int *) ctx), buf, len ); 00280 00281 if( len > 0 && ret == 0 ) 00282 return( XYSSL_ERR_NET_CONN_RESET ); 00283 00284 if( ret < 0 ) 00285 { 00286 if( net_is_blocking() != 0 ) 00287 return( XYSSL_ERR_NET_TRY_AGAIN ); 00288 00289 #if defined(WIN32) || defined(_WIN32_WCE) 00290 if( WSAGetLastError() == WSAECONNRESET ) 00291 return( XYSSL_ERR_NET_CONN_RESET ); 00292 #else 00293 if( errno == EPIPE || errno == ECONNRESET ) 00294 return( XYSSL_ERR_NET_CONN_RESET ); 00295 00296 if( errno == EINTR ) 00297 return( XYSSL_ERR_NET_TRY_AGAIN ); 00298 #endif 00299 00300 return( XYSSL_ERR_NET_RECV_FAILED ); 00301 } 00302 00303 return( ret ); 00304 } 00305 00306 /* 00307 * Write at most 'len' characters 00308 */ 00309 int net_send( void *ctx, unsigned char *buf, int len ) 00310 { 00311 int ret = write( *((int *) ctx), buf, len ); 00312 00313 if( ret < 0 ) 00314 { 00315 if( net_is_blocking() != 0 ) 00316 return( XYSSL_ERR_NET_TRY_AGAIN ); 00317 00318 #if defined(WIN32) || defined(_WIN32_WCE) 00319 if( WSAGetLastError() == WSAECONNRESET ) 00320 return( XYSSL_ERR_NET_CONN_RESET ); 00321 #else 00322 if( errno == EPIPE || errno == ECONNRESET ) 00323 return( XYSSL_ERR_NET_CONN_RESET ); 00324 00325 if( errno == EINTR ) 00326 return( XYSSL_ERR_NET_TRY_AGAIN ); 00327 #endif 00328 00329 return( XYSSL_ERR_NET_SEND_FAILED ); 00330 } 00331 00332 return( ret ); 00333 } 00334 00335 /* 00336 * Gracefully close the connection 00337 */ 00338 void net_close( int fd ) 00339 { 00340 shutdown( fd, 2 ); 00341 close( fd ); 00342 } 00343 00344 #endif