nkjnm

Dependencies:   MAX44000 nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

Committer:
nitsshukla
Date:
Fri Nov 04 12:06:04 2016 +0000
Revision:
7:3a65ef12ba31
Parent:
1:55a6170b404f
kghj;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
nexpaq 1:55a6170b404f 1 /*
nexpaq 1:55a6170b404f 2 * TCP/IP or UDP/IP networking functions
nexpaq 1:55a6170b404f 3 *
nexpaq 1:55a6170b404f 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
nexpaq 1:55a6170b404f 5 * SPDX-License-Identifier: Apache-2.0
nexpaq 1:55a6170b404f 6 *
nexpaq 1:55a6170b404f 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
nexpaq 1:55a6170b404f 8 * not use this file except in compliance with the License.
nexpaq 1:55a6170b404f 9 * You may obtain a copy of the License at
nexpaq 1:55a6170b404f 10 *
nexpaq 1:55a6170b404f 11 * http://www.apache.org/licenses/LICENSE-2.0
nexpaq 1:55a6170b404f 12 *
nexpaq 1:55a6170b404f 13 * Unless required by applicable law or agreed to in writing, software
nexpaq 1:55a6170b404f 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
nexpaq 1:55a6170b404f 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
nexpaq 1:55a6170b404f 16 * See the License for the specific language governing permissions and
nexpaq 1:55a6170b404f 17 * limitations under the License.
nexpaq 1:55a6170b404f 18 *
nexpaq 1:55a6170b404f 19 * This file is part of mbed TLS (https://tls.mbed.org)
nexpaq 1:55a6170b404f 20 */
nexpaq 1:55a6170b404f 21
nexpaq 1:55a6170b404f 22 #if !defined(MBEDTLS_CONFIG_FILE)
nexpaq 1:55a6170b404f 23 #include "mbedtls/config.h"
nexpaq 1:55a6170b404f 24 #else
nexpaq 1:55a6170b404f 25 #include MBEDTLS_CONFIG_FILE
nexpaq 1:55a6170b404f 26 #endif
nexpaq 1:55a6170b404f 27
nexpaq 1:55a6170b404f 28 #if defined(MBEDTLS_NET_C)
nexpaq 1:55a6170b404f 29
nexpaq 1:55a6170b404f 30 #if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
nexpaq 1:55a6170b404f 31 !defined(__APPLE__) && !defined(_WIN32)
nexpaq 1:55a6170b404f 32 #error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
nexpaq 1:55a6170b404f 33 #endif
nexpaq 1:55a6170b404f 34
nexpaq 1:55a6170b404f 35 #if defined(MBEDTLS_PLATFORM_C)
nexpaq 1:55a6170b404f 36 #include "mbedtls/platform.h"
nexpaq 1:55a6170b404f 37 #else
nexpaq 1:55a6170b404f 38 #include <stdlib.h>
nexpaq 1:55a6170b404f 39 #define mbedtls_time_t time_t
nexpaq 1:55a6170b404f 40 #endif
nexpaq 1:55a6170b404f 41
nexpaq 1:55a6170b404f 42 #include "mbedtls/net.h"
nexpaq 1:55a6170b404f 43
nexpaq 1:55a6170b404f 44 #include <string.h>
nexpaq 1:55a6170b404f 45
nexpaq 1:55a6170b404f 46 #if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
nexpaq 1:55a6170b404f 47 !defined(EFI32)
nexpaq 1:55a6170b404f 48
nexpaq 1:55a6170b404f 49 #ifdef _WIN32_WINNT
nexpaq 1:55a6170b404f 50 #undef _WIN32_WINNT
nexpaq 1:55a6170b404f 51 #endif
nexpaq 1:55a6170b404f 52 /* Enables getaddrinfo() & Co */
nexpaq 1:55a6170b404f 53 #define _WIN32_WINNT 0x0501
nexpaq 1:55a6170b404f 54 #include <ws2tcpip.h>
nexpaq 1:55a6170b404f 55
nexpaq 1:55a6170b404f 56 #include <winsock2.h>
nexpaq 1:55a6170b404f 57 #include <windows.h>
nexpaq 1:55a6170b404f 58
nexpaq 1:55a6170b404f 59 #if defined(_MSC_VER)
nexpaq 1:55a6170b404f 60 #if defined(_WIN32_WCE)
nexpaq 1:55a6170b404f 61 #pragma comment( lib, "ws2.lib" )
nexpaq 1:55a6170b404f 62 #else
nexpaq 1:55a6170b404f 63 #pragma comment( lib, "ws2_32.lib" )
nexpaq 1:55a6170b404f 64 #endif
nexpaq 1:55a6170b404f 65 #endif /* _MSC_VER */
nexpaq 1:55a6170b404f 66
nexpaq 1:55a6170b404f 67 #define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0)
nexpaq 1:55a6170b404f 68 #define write(fd,buf,len) send(fd,(char*)buf,(int) len,0)
nexpaq 1:55a6170b404f 69 #define close(fd) closesocket(fd)
nexpaq 1:55a6170b404f 70
nexpaq 1:55a6170b404f 71 static int wsa_init_done = 0;
nexpaq 1:55a6170b404f 72
nexpaq 1:55a6170b404f 73 #else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
nexpaq 1:55a6170b404f 74
nexpaq 1:55a6170b404f 75 #include <sys/types.h>
nexpaq 1:55a6170b404f 76 #include <sys/socket.h>
nexpaq 1:55a6170b404f 77 #include <netinet/in.h>
nexpaq 1:55a6170b404f 78 #include <arpa/inet.h>
nexpaq 1:55a6170b404f 79 #include <sys/time.h>
nexpaq 1:55a6170b404f 80 #include <unistd.h>
nexpaq 1:55a6170b404f 81 #include <signal.h>
nexpaq 1:55a6170b404f 82 #include <fcntl.h>
nexpaq 1:55a6170b404f 83 #include <netdb.h>
nexpaq 1:55a6170b404f 84 #include <errno.h>
nexpaq 1:55a6170b404f 85
nexpaq 1:55a6170b404f 86 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
nexpaq 1:55a6170b404f 87
nexpaq 1:55a6170b404f 88 /* Some MS functions want int and MSVC warns if we pass size_t,
nexpaq 1:55a6170b404f 89 * but the standard fucntions use socklen_t, so cast only for MSVC */
nexpaq 1:55a6170b404f 90 #if defined(_MSC_VER)
nexpaq 1:55a6170b404f 91 #define MSVC_INT_CAST (int)
nexpaq 1:55a6170b404f 92 #else
nexpaq 1:55a6170b404f 93 #define MSVC_INT_CAST
nexpaq 1:55a6170b404f 94 #endif
nexpaq 1:55a6170b404f 95
nexpaq 1:55a6170b404f 96 #include <stdio.h>
nexpaq 1:55a6170b404f 97
nexpaq 1:55a6170b404f 98 #include <time.h>
nexpaq 1:55a6170b404f 99
nexpaq 1:55a6170b404f 100 #include <stdint.h>
nexpaq 1:55a6170b404f 101
nexpaq 1:55a6170b404f 102 /*
nexpaq 1:55a6170b404f 103 * Prepare for using the sockets interface
nexpaq 1:55a6170b404f 104 */
nexpaq 1:55a6170b404f 105 static int net_prepare( void )
nexpaq 1:55a6170b404f 106 {
nexpaq 1:55a6170b404f 107 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
nexpaq 1:55a6170b404f 108 !defined(EFI32)
nexpaq 1:55a6170b404f 109 WSADATA wsaData;
nexpaq 1:55a6170b404f 110
nexpaq 1:55a6170b404f 111 if( wsa_init_done == 0 )
nexpaq 1:55a6170b404f 112 {
nexpaq 1:55a6170b404f 113 if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
nexpaq 1:55a6170b404f 114 return( MBEDTLS_ERR_NET_SOCKET_FAILED );
nexpaq 1:55a6170b404f 115
nexpaq 1:55a6170b404f 116 wsa_init_done = 1;
nexpaq 1:55a6170b404f 117 }
nexpaq 1:55a6170b404f 118 #else
nexpaq 1:55a6170b404f 119 #if !defined(EFIX64) && !defined(EFI32)
nexpaq 1:55a6170b404f 120 signal( SIGPIPE, SIG_IGN );
nexpaq 1:55a6170b404f 121 #endif
nexpaq 1:55a6170b404f 122 #endif
nexpaq 1:55a6170b404f 123 return( 0 );
nexpaq 1:55a6170b404f 124 }
nexpaq 1:55a6170b404f 125
nexpaq 1:55a6170b404f 126 /*
nexpaq 1:55a6170b404f 127 * Initialize a context
nexpaq 1:55a6170b404f 128 */
nexpaq 1:55a6170b404f 129 void mbedtls_net_init( mbedtls_net_context *ctx )
nexpaq 1:55a6170b404f 130 {
nexpaq 1:55a6170b404f 131 ctx->fd = -1;
nexpaq 1:55a6170b404f 132 }
nexpaq 1:55a6170b404f 133
nexpaq 1:55a6170b404f 134 /*
nexpaq 1:55a6170b404f 135 * Initiate a TCP connection with host:port and the given protocol
nexpaq 1:55a6170b404f 136 */
nexpaq 1:55a6170b404f 137 int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
nexpaq 1:55a6170b404f 138 {
nexpaq 1:55a6170b404f 139 int ret;
nexpaq 1:55a6170b404f 140 struct addrinfo hints, *addr_list, *cur;
nexpaq 1:55a6170b404f 141
nexpaq 1:55a6170b404f 142 if( ( ret = net_prepare() ) != 0 )
nexpaq 1:55a6170b404f 143 return( ret );
nexpaq 1:55a6170b404f 144
nexpaq 1:55a6170b404f 145 /* Do name resolution with both IPv6 and IPv4 */
nexpaq 1:55a6170b404f 146 memset( &hints, 0, sizeof( hints ) );
nexpaq 1:55a6170b404f 147 hints.ai_family = AF_UNSPEC;
nexpaq 1:55a6170b404f 148 hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
nexpaq 1:55a6170b404f 149 hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
nexpaq 1:55a6170b404f 150
nexpaq 1:55a6170b404f 151 if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
nexpaq 1:55a6170b404f 152 return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
nexpaq 1:55a6170b404f 153
nexpaq 1:55a6170b404f 154 /* Try the sockaddrs until a connection succeeds */
nexpaq 1:55a6170b404f 155 ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
nexpaq 1:55a6170b404f 156 for( cur = addr_list; cur != NULL; cur = cur->ai_next )
nexpaq 1:55a6170b404f 157 {
nexpaq 1:55a6170b404f 158 ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
nexpaq 1:55a6170b404f 159 cur->ai_protocol );
nexpaq 1:55a6170b404f 160 if( ctx->fd < 0 )
nexpaq 1:55a6170b404f 161 {
nexpaq 1:55a6170b404f 162 ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
nexpaq 1:55a6170b404f 163 continue;
nexpaq 1:55a6170b404f 164 }
nexpaq 1:55a6170b404f 165
nexpaq 1:55a6170b404f 166 if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 )
nexpaq 1:55a6170b404f 167 {
nexpaq 1:55a6170b404f 168 ret = 0;
nexpaq 1:55a6170b404f 169 break;
nexpaq 1:55a6170b404f 170 }
nexpaq 1:55a6170b404f 171
nexpaq 1:55a6170b404f 172 close( ctx->fd );
nexpaq 1:55a6170b404f 173 ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
nexpaq 1:55a6170b404f 174 }
nexpaq 1:55a6170b404f 175
nexpaq 1:55a6170b404f 176 freeaddrinfo( addr_list );
nexpaq 1:55a6170b404f 177
nexpaq 1:55a6170b404f 178 return( ret );
nexpaq 1:55a6170b404f 179 }
nexpaq 1:55a6170b404f 180
nexpaq 1:55a6170b404f 181 /*
nexpaq 1:55a6170b404f 182 * Create a listening socket on bind_ip:port
nexpaq 1:55a6170b404f 183 */
nexpaq 1:55a6170b404f 184 int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
nexpaq 1:55a6170b404f 185 {
nexpaq 1:55a6170b404f 186 int n, ret;
nexpaq 1:55a6170b404f 187 struct addrinfo hints, *addr_list, *cur;
nexpaq 1:55a6170b404f 188
nexpaq 1:55a6170b404f 189 if( ( ret = net_prepare() ) != 0 )
nexpaq 1:55a6170b404f 190 return( ret );
nexpaq 1:55a6170b404f 191
nexpaq 1:55a6170b404f 192 /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
nexpaq 1:55a6170b404f 193 memset( &hints, 0, sizeof( hints ) );
nexpaq 1:55a6170b404f 194 hints.ai_family = AF_UNSPEC;
nexpaq 1:55a6170b404f 195 hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
nexpaq 1:55a6170b404f 196 hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
nexpaq 1:55a6170b404f 197 if( bind_ip == NULL )
nexpaq 1:55a6170b404f 198 hints.ai_flags = AI_PASSIVE;
nexpaq 1:55a6170b404f 199
nexpaq 1:55a6170b404f 200 if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
nexpaq 1:55a6170b404f 201 return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
nexpaq 1:55a6170b404f 202
nexpaq 1:55a6170b404f 203 /* Try the sockaddrs until a binding succeeds */
nexpaq 1:55a6170b404f 204 ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
nexpaq 1:55a6170b404f 205 for( cur = addr_list; cur != NULL; cur = cur->ai_next )
nexpaq 1:55a6170b404f 206 {
nexpaq 1:55a6170b404f 207 ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
nexpaq 1:55a6170b404f 208 cur->ai_protocol );
nexpaq 1:55a6170b404f 209 if( ctx->fd < 0 )
nexpaq 1:55a6170b404f 210 {
nexpaq 1:55a6170b404f 211 ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
nexpaq 1:55a6170b404f 212 continue;
nexpaq 1:55a6170b404f 213 }
nexpaq 1:55a6170b404f 214
nexpaq 1:55a6170b404f 215 n = 1;
nexpaq 1:55a6170b404f 216 if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
nexpaq 1:55a6170b404f 217 (const char *) &n, sizeof( n ) ) != 0 )
nexpaq 1:55a6170b404f 218 {
nexpaq 1:55a6170b404f 219 close( ctx->fd );
nexpaq 1:55a6170b404f 220 ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
nexpaq 1:55a6170b404f 221 continue;
nexpaq 1:55a6170b404f 222 }
nexpaq 1:55a6170b404f 223
nexpaq 1:55a6170b404f 224 if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 )
nexpaq 1:55a6170b404f 225 {
nexpaq 1:55a6170b404f 226 close( ctx->fd );
nexpaq 1:55a6170b404f 227 ret = MBEDTLS_ERR_NET_BIND_FAILED;
nexpaq 1:55a6170b404f 228 continue;
nexpaq 1:55a6170b404f 229 }
nexpaq 1:55a6170b404f 230
nexpaq 1:55a6170b404f 231 /* Listen only makes sense for TCP */
nexpaq 1:55a6170b404f 232 if( proto == MBEDTLS_NET_PROTO_TCP )
nexpaq 1:55a6170b404f 233 {
nexpaq 1:55a6170b404f 234 if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
nexpaq 1:55a6170b404f 235 {
nexpaq 1:55a6170b404f 236 close( ctx->fd );
nexpaq 1:55a6170b404f 237 ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
nexpaq 1:55a6170b404f 238 continue;
nexpaq 1:55a6170b404f 239 }
nexpaq 1:55a6170b404f 240 }
nexpaq 1:55a6170b404f 241
nexpaq 1:55a6170b404f 242 /* I we ever get there, it's a success */
nexpaq 1:55a6170b404f 243 ret = 0;
nexpaq 1:55a6170b404f 244 break;
nexpaq 1:55a6170b404f 245 }
nexpaq 1:55a6170b404f 246
nexpaq 1:55a6170b404f 247 freeaddrinfo( addr_list );
nexpaq 1:55a6170b404f 248
nexpaq 1:55a6170b404f 249 return( ret );
nexpaq 1:55a6170b404f 250
nexpaq 1:55a6170b404f 251 }
nexpaq 1:55a6170b404f 252
nexpaq 1:55a6170b404f 253 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
nexpaq 1:55a6170b404f 254 !defined(EFI32)
nexpaq 1:55a6170b404f 255 /*
nexpaq 1:55a6170b404f 256 * Check if the requested operation would be blocking on a non-blocking socket
nexpaq 1:55a6170b404f 257 * and thus 'failed' with a negative return value.
nexpaq 1:55a6170b404f 258 */
nexpaq 1:55a6170b404f 259 static int net_would_block( const mbedtls_net_context *ctx )
nexpaq 1:55a6170b404f 260 {
nexpaq 1:55a6170b404f 261 ((void) ctx);
nexpaq 1:55a6170b404f 262 return( WSAGetLastError() == WSAEWOULDBLOCK );
nexpaq 1:55a6170b404f 263 }
nexpaq 1:55a6170b404f 264 #else
nexpaq 1:55a6170b404f 265 /*
nexpaq 1:55a6170b404f 266 * Check if the requested operation would be blocking on a non-blocking socket
nexpaq 1:55a6170b404f 267 * and thus 'failed' with a negative return value.
nexpaq 1:55a6170b404f 268 *
nexpaq 1:55a6170b404f 269 * Note: on a blocking socket this function always returns 0!
nexpaq 1:55a6170b404f 270 */
nexpaq 1:55a6170b404f 271 static int net_would_block( const mbedtls_net_context *ctx )
nexpaq 1:55a6170b404f 272 {
nexpaq 1:55a6170b404f 273 /*
nexpaq 1:55a6170b404f 274 * Never return 'WOULD BLOCK' on a non-blocking socket
nexpaq 1:55a6170b404f 275 */
nexpaq 1:55a6170b404f 276 if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK )
nexpaq 1:55a6170b404f 277 return( 0 );
nexpaq 1:55a6170b404f 278
nexpaq 1:55a6170b404f 279 switch( errno )
nexpaq 1:55a6170b404f 280 {
nexpaq 1:55a6170b404f 281 #if defined EAGAIN
nexpaq 1:55a6170b404f 282 case EAGAIN:
nexpaq 1:55a6170b404f 283 #endif
nexpaq 1:55a6170b404f 284 #if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
nexpaq 1:55a6170b404f 285 case EWOULDBLOCK:
nexpaq 1:55a6170b404f 286 #endif
nexpaq 1:55a6170b404f 287 return( 1 );
nexpaq 1:55a6170b404f 288 }
nexpaq 1:55a6170b404f 289 return( 0 );
nexpaq 1:55a6170b404f 290 }
nexpaq 1:55a6170b404f 291 #endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
nexpaq 1:55a6170b404f 292
nexpaq 1:55a6170b404f 293 /*
nexpaq 1:55a6170b404f 294 * Accept a connection from a remote client
nexpaq 1:55a6170b404f 295 */
nexpaq 1:55a6170b404f 296 int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
nexpaq 1:55a6170b404f 297 mbedtls_net_context *client_ctx,
nexpaq 1:55a6170b404f 298 void *client_ip, size_t buf_size, size_t *ip_len )
nexpaq 1:55a6170b404f 299 {
nexpaq 1:55a6170b404f 300 int ret;
nexpaq 1:55a6170b404f 301 int type;
nexpaq 1:55a6170b404f 302
nexpaq 1:55a6170b404f 303 struct sockaddr_storage client_addr;
nexpaq 1:55a6170b404f 304
nexpaq 1:55a6170b404f 305 #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
nexpaq 1:55a6170b404f 306 defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
nexpaq 1:55a6170b404f 307 socklen_t n = (socklen_t) sizeof( client_addr );
nexpaq 1:55a6170b404f 308 socklen_t type_len = (socklen_t) sizeof( type );
nexpaq 1:55a6170b404f 309 #else
nexpaq 1:55a6170b404f 310 int n = (int) sizeof( client_addr );
nexpaq 1:55a6170b404f 311 int type_len = (int) sizeof( type );
nexpaq 1:55a6170b404f 312 #endif
nexpaq 1:55a6170b404f 313
nexpaq 1:55a6170b404f 314 /* Is this a TCP or UDP socket? */
nexpaq 1:55a6170b404f 315 if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
nexpaq 1:55a6170b404f 316 (void *) &type, &type_len ) != 0 ||
nexpaq 1:55a6170b404f 317 ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
nexpaq 1:55a6170b404f 318 {
nexpaq 1:55a6170b404f 319 return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
nexpaq 1:55a6170b404f 320 }
nexpaq 1:55a6170b404f 321
nexpaq 1:55a6170b404f 322 if( type == SOCK_STREAM )
nexpaq 1:55a6170b404f 323 {
nexpaq 1:55a6170b404f 324 /* TCP: actual accept() */
nexpaq 1:55a6170b404f 325 ret = client_ctx->fd = (int) accept( bind_ctx->fd,
nexpaq 1:55a6170b404f 326 (struct sockaddr *) &client_addr, &n );
nexpaq 1:55a6170b404f 327 }
nexpaq 1:55a6170b404f 328 else
nexpaq 1:55a6170b404f 329 {
nexpaq 1:55a6170b404f 330 /* UDP: wait for a message, but keep it in the queue */
nexpaq 1:55a6170b404f 331 char buf[1] = { 0 };
nexpaq 1:55a6170b404f 332
nexpaq 1:55a6170b404f 333 ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
nexpaq 1:55a6170b404f 334 (struct sockaddr *) &client_addr, &n );
nexpaq 1:55a6170b404f 335
nexpaq 1:55a6170b404f 336 #if defined(_WIN32)
nexpaq 1:55a6170b404f 337 if( ret == SOCKET_ERROR &&
nexpaq 1:55a6170b404f 338 WSAGetLastError() == WSAEMSGSIZE )
nexpaq 1:55a6170b404f 339 {
nexpaq 1:55a6170b404f 340 /* We know buf is too small, thanks, just peeking here */
nexpaq 1:55a6170b404f 341 ret = 0;
nexpaq 1:55a6170b404f 342 }
nexpaq 1:55a6170b404f 343 #endif
nexpaq 1:55a6170b404f 344 }
nexpaq 1:55a6170b404f 345
nexpaq 1:55a6170b404f 346 if( ret < 0 )
nexpaq 1:55a6170b404f 347 {
nexpaq 1:55a6170b404f 348 if( net_would_block( bind_ctx ) != 0 )
nexpaq 1:55a6170b404f 349 return( MBEDTLS_ERR_SSL_WANT_READ );
nexpaq 1:55a6170b404f 350
nexpaq 1:55a6170b404f 351 return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
nexpaq 1:55a6170b404f 352 }
nexpaq 1:55a6170b404f 353
nexpaq 1:55a6170b404f 354 /* UDP: hijack the listening socket to communicate with the client,
nexpaq 1:55a6170b404f 355 * then bind a new socket to accept new connections */
nexpaq 1:55a6170b404f 356 if( type != SOCK_STREAM )
nexpaq 1:55a6170b404f 357 {
nexpaq 1:55a6170b404f 358 struct sockaddr_storage local_addr;
nexpaq 1:55a6170b404f 359 int one = 1;
nexpaq 1:55a6170b404f 360
nexpaq 1:55a6170b404f 361 if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
nexpaq 1:55a6170b404f 362 return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
nexpaq 1:55a6170b404f 363
nexpaq 1:55a6170b404f 364 client_ctx->fd = bind_ctx->fd;
nexpaq 1:55a6170b404f 365 bind_ctx->fd = -1; /* In case we exit early */
nexpaq 1:55a6170b404f 366
nexpaq 1:55a6170b404f 367 n = sizeof( struct sockaddr_storage );
nexpaq 1:55a6170b404f 368 if( getsockname( client_ctx->fd,
nexpaq 1:55a6170b404f 369 (struct sockaddr *) &local_addr, &n ) != 0 ||
nexpaq 1:55a6170b404f 370 ( bind_ctx->fd = (int) socket( local_addr.ss_family,
nexpaq 1:55a6170b404f 371 SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
nexpaq 1:55a6170b404f 372 setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
nexpaq 1:55a6170b404f 373 (const char *) &one, sizeof( one ) ) != 0 )
nexpaq 1:55a6170b404f 374 {
nexpaq 1:55a6170b404f 375 return( MBEDTLS_ERR_NET_SOCKET_FAILED );
nexpaq 1:55a6170b404f 376 }
nexpaq 1:55a6170b404f 377
nexpaq 1:55a6170b404f 378 if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
nexpaq 1:55a6170b404f 379 {
nexpaq 1:55a6170b404f 380 return( MBEDTLS_ERR_NET_BIND_FAILED );
nexpaq 1:55a6170b404f 381 }
nexpaq 1:55a6170b404f 382 }
nexpaq 1:55a6170b404f 383
nexpaq 1:55a6170b404f 384 if( client_ip != NULL )
nexpaq 1:55a6170b404f 385 {
nexpaq 1:55a6170b404f 386 if( client_addr.ss_family == AF_INET )
nexpaq 1:55a6170b404f 387 {
nexpaq 1:55a6170b404f 388 struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
nexpaq 1:55a6170b404f 389 *ip_len = sizeof( addr4->sin_addr.s_addr );
nexpaq 1:55a6170b404f 390
nexpaq 1:55a6170b404f 391 if( buf_size < *ip_len )
nexpaq 1:55a6170b404f 392 return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
nexpaq 1:55a6170b404f 393
nexpaq 1:55a6170b404f 394 memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
nexpaq 1:55a6170b404f 395 }
nexpaq 1:55a6170b404f 396 else
nexpaq 1:55a6170b404f 397 {
nexpaq 1:55a6170b404f 398 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
nexpaq 1:55a6170b404f 399 *ip_len = sizeof( addr6->sin6_addr.s6_addr );
nexpaq 1:55a6170b404f 400
nexpaq 1:55a6170b404f 401 if( buf_size < *ip_len )
nexpaq 1:55a6170b404f 402 return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
nexpaq 1:55a6170b404f 403
nexpaq 1:55a6170b404f 404 memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
nexpaq 1:55a6170b404f 405 }
nexpaq 1:55a6170b404f 406 }
nexpaq 1:55a6170b404f 407
nexpaq 1:55a6170b404f 408 return( 0 );
nexpaq 1:55a6170b404f 409 }
nexpaq 1:55a6170b404f 410
nexpaq 1:55a6170b404f 411 /*
nexpaq 1:55a6170b404f 412 * Set the socket blocking or non-blocking
nexpaq 1:55a6170b404f 413 */
nexpaq 1:55a6170b404f 414 int mbedtls_net_set_block( mbedtls_net_context *ctx )
nexpaq 1:55a6170b404f 415 {
nexpaq 1:55a6170b404f 416 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
nexpaq 1:55a6170b404f 417 !defined(EFI32)
nexpaq 1:55a6170b404f 418 u_long n = 0;
nexpaq 1:55a6170b404f 419 return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
nexpaq 1:55a6170b404f 420 #else
nexpaq 1:55a6170b404f 421 return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) );
nexpaq 1:55a6170b404f 422 #endif
nexpaq 1:55a6170b404f 423 }
nexpaq 1:55a6170b404f 424
nexpaq 1:55a6170b404f 425 int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
nexpaq 1:55a6170b404f 426 {
nexpaq 1:55a6170b404f 427 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
nexpaq 1:55a6170b404f 428 !defined(EFI32)
nexpaq 1:55a6170b404f 429 u_long n = 1;
nexpaq 1:55a6170b404f 430 return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
nexpaq 1:55a6170b404f 431 #else
nexpaq 1:55a6170b404f 432 return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) );
nexpaq 1:55a6170b404f 433 #endif
nexpaq 1:55a6170b404f 434 }
nexpaq 1:55a6170b404f 435
nexpaq 1:55a6170b404f 436 /*
nexpaq 1:55a6170b404f 437 * Portable usleep helper
nexpaq 1:55a6170b404f 438 */
nexpaq 1:55a6170b404f 439 void mbedtls_net_usleep( unsigned long usec )
nexpaq 1:55a6170b404f 440 {
nexpaq 1:55a6170b404f 441 #if defined(_WIN32)
nexpaq 1:55a6170b404f 442 Sleep( ( usec + 999 ) / 1000 );
nexpaq 1:55a6170b404f 443 #else
nexpaq 1:55a6170b404f 444 struct timeval tv;
nexpaq 1:55a6170b404f 445 tv.tv_sec = usec / 1000000;
nexpaq 1:55a6170b404f 446 #if defined(__unix__) || defined(__unix) || \
nexpaq 1:55a6170b404f 447 ( defined(__APPLE__) && defined(__MACH__) )
nexpaq 1:55a6170b404f 448 tv.tv_usec = (suseconds_t) usec % 1000000;
nexpaq 1:55a6170b404f 449 #else
nexpaq 1:55a6170b404f 450 tv.tv_usec = usec % 1000000;
nexpaq 1:55a6170b404f 451 #endif
nexpaq 1:55a6170b404f 452 select( 0, NULL, NULL, NULL, &tv );
nexpaq 1:55a6170b404f 453 #endif
nexpaq 1:55a6170b404f 454 }
nexpaq 1:55a6170b404f 455
nexpaq 1:55a6170b404f 456 /*
nexpaq 1:55a6170b404f 457 * Read at most 'len' characters
nexpaq 1:55a6170b404f 458 */
nexpaq 1:55a6170b404f 459 int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
nexpaq 1:55a6170b404f 460 {
nexpaq 1:55a6170b404f 461 int ret;
nexpaq 1:55a6170b404f 462 int fd = ((mbedtls_net_context *) ctx)->fd;
nexpaq 1:55a6170b404f 463
nexpaq 1:55a6170b404f 464 if( fd < 0 )
nexpaq 1:55a6170b404f 465 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
nexpaq 1:55a6170b404f 466
nexpaq 1:55a6170b404f 467 ret = (int) read( fd, buf, len );
nexpaq 1:55a6170b404f 468
nexpaq 1:55a6170b404f 469 if( ret < 0 )
nexpaq 1:55a6170b404f 470 {
nexpaq 1:55a6170b404f 471 if( net_would_block( ctx ) != 0 )
nexpaq 1:55a6170b404f 472 return( MBEDTLS_ERR_SSL_WANT_READ );
nexpaq 1:55a6170b404f 473
nexpaq 1:55a6170b404f 474 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
nexpaq 1:55a6170b404f 475 !defined(EFI32)
nexpaq 1:55a6170b404f 476 if( WSAGetLastError() == WSAECONNRESET )
nexpaq 1:55a6170b404f 477 return( MBEDTLS_ERR_NET_CONN_RESET );
nexpaq 1:55a6170b404f 478 #else
nexpaq 1:55a6170b404f 479 if( errno == EPIPE || errno == ECONNRESET )
nexpaq 1:55a6170b404f 480 return( MBEDTLS_ERR_NET_CONN_RESET );
nexpaq 1:55a6170b404f 481
nexpaq 1:55a6170b404f 482 if( errno == EINTR )
nexpaq 1:55a6170b404f 483 return( MBEDTLS_ERR_SSL_WANT_READ );
nexpaq 1:55a6170b404f 484 #endif
nexpaq 1:55a6170b404f 485
nexpaq 1:55a6170b404f 486 return( MBEDTLS_ERR_NET_RECV_FAILED );
nexpaq 1:55a6170b404f 487 }
nexpaq 1:55a6170b404f 488
nexpaq 1:55a6170b404f 489 return( ret );
nexpaq 1:55a6170b404f 490 }
nexpaq 1:55a6170b404f 491
nexpaq 1:55a6170b404f 492 /*
nexpaq 1:55a6170b404f 493 * Read at most 'len' characters, blocking for at most 'timeout' ms
nexpaq 1:55a6170b404f 494 */
nexpaq 1:55a6170b404f 495 int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
nexpaq 1:55a6170b404f 496 uint32_t timeout )
nexpaq 1:55a6170b404f 497 {
nexpaq 1:55a6170b404f 498 int ret;
nexpaq 1:55a6170b404f 499 struct timeval tv;
nexpaq 1:55a6170b404f 500 fd_set read_fds;
nexpaq 1:55a6170b404f 501 int fd = ((mbedtls_net_context *) ctx)->fd;
nexpaq 1:55a6170b404f 502
nexpaq 1:55a6170b404f 503 if( fd < 0 )
nexpaq 1:55a6170b404f 504 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
nexpaq 1:55a6170b404f 505
nexpaq 1:55a6170b404f 506 FD_ZERO( &read_fds );
nexpaq 1:55a6170b404f 507 FD_SET( fd, &read_fds );
nexpaq 1:55a6170b404f 508
nexpaq 1:55a6170b404f 509 tv.tv_sec = timeout / 1000;
nexpaq 1:55a6170b404f 510 tv.tv_usec = ( timeout % 1000 ) * 1000;
nexpaq 1:55a6170b404f 511
nexpaq 1:55a6170b404f 512 ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
nexpaq 1:55a6170b404f 513
nexpaq 1:55a6170b404f 514 /* Zero fds ready means we timed out */
nexpaq 1:55a6170b404f 515 if( ret == 0 )
nexpaq 1:55a6170b404f 516 return( MBEDTLS_ERR_SSL_TIMEOUT );
nexpaq 1:55a6170b404f 517
nexpaq 1:55a6170b404f 518 if( ret < 0 )
nexpaq 1:55a6170b404f 519 {
nexpaq 1:55a6170b404f 520 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
nexpaq 1:55a6170b404f 521 !defined(EFI32)
nexpaq 1:55a6170b404f 522 if( WSAGetLastError() == WSAEINTR )
nexpaq 1:55a6170b404f 523 return( MBEDTLS_ERR_SSL_WANT_READ );
nexpaq 1:55a6170b404f 524 #else
nexpaq 1:55a6170b404f 525 if( errno == EINTR )
nexpaq 1:55a6170b404f 526 return( MBEDTLS_ERR_SSL_WANT_READ );
nexpaq 1:55a6170b404f 527 #endif
nexpaq 1:55a6170b404f 528
nexpaq 1:55a6170b404f 529 return( MBEDTLS_ERR_NET_RECV_FAILED );
nexpaq 1:55a6170b404f 530 }
nexpaq 1:55a6170b404f 531
nexpaq 1:55a6170b404f 532 /* This call will not block */
nexpaq 1:55a6170b404f 533 return( mbedtls_net_recv( ctx, buf, len ) );
nexpaq 1:55a6170b404f 534 }
nexpaq 1:55a6170b404f 535
nexpaq 1:55a6170b404f 536 /*
nexpaq 1:55a6170b404f 537 * Write at most 'len' characters
nexpaq 1:55a6170b404f 538 */
nexpaq 1:55a6170b404f 539 int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
nexpaq 1:55a6170b404f 540 {
nexpaq 1:55a6170b404f 541 int ret;
nexpaq 1:55a6170b404f 542 int fd = ((mbedtls_net_context *) ctx)->fd;
nexpaq 1:55a6170b404f 543
nexpaq 1:55a6170b404f 544 if( fd < 0 )
nexpaq 1:55a6170b404f 545 return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
nexpaq 1:55a6170b404f 546
nexpaq 1:55a6170b404f 547 ret = (int) write( fd, buf, len );
nexpaq 1:55a6170b404f 548
nexpaq 1:55a6170b404f 549 if( ret < 0 )
nexpaq 1:55a6170b404f 550 {
nexpaq 1:55a6170b404f 551 if( net_would_block( ctx ) != 0 )
nexpaq 1:55a6170b404f 552 return( MBEDTLS_ERR_SSL_WANT_WRITE );
nexpaq 1:55a6170b404f 553
nexpaq 1:55a6170b404f 554 #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
nexpaq 1:55a6170b404f 555 !defined(EFI32)
nexpaq 1:55a6170b404f 556 if( WSAGetLastError() == WSAECONNRESET )
nexpaq 1:55a6170b404f 557 return( MBEDTLS_ERR_NET_CONN_RESET );
nexpaq 1:55a6170b404f 558 #else
nexpaq 1:55a6170b404f 559 if( errno == EPIPE || errno == ECONNRESET )
nexpaq 1:55a6170b404f 560 return( MBEDTLS_ERR_NET_CONN_RESET );
nexpaq 1:55a6170b404f 561
nexpaq 1:55a6170b404f 562 if( errno == EINTR )
nexpaq 1:55a6170b404f 563 return( MBEDTLS_ERR_SSL_WANT_WRITE );
nexpaq 1:55a6170b404f 564 #endif
nexpaq 1:55a6170b404f 565
nexpaq 1:55a6170b404f 566 return( MBEDTLS_ERR_NET_SEND_FAILED );
nexpaq 1:55a6170b404f 567 }
nexpaq 1:55a6170b404f 568
nexpaq 1:55a6170b404f 569 return( ret );
nexpaq 1:55a6170b404f 570 }
nexpaq 1:55a6170b404f 571
nexpaq 1:55a6170b404f 572 /*
nexpaq 1:55a6170b404f 573 * Gracefully close the connection
nexpaq 1:55a6170b404f 574 */
nexpaq 1:55a6170b404f 575 void mbedtls_net_free( mbedtls_net_context *ctx )
nexpaq 1:55a6170b404f 576 {
nexpaq 1:55a6170b404f 577 if( ctx->fd == -1 )
nexpaq 1:55a6170b404f 578 return;
nexpaq 1:55a6170b404f 579
nexpaq 1:55a6170b404f 580 shutdown( ctx->fd, 2 );
nexpaq 1:55a6170b404f 581 close( ctx->fd );
nexpaq 1:55a6170b404f 582
nexpaq 1:55a6170b404f 583 ctx->fd = -1;
nexpaq 1:55a6170b404f 584 }
nexpaq 1:55a6170b404f 585
nexpaq 1:55a6170b404f 586 #endif /* MBEDTLS_NET_C */