I added functionality to get the RSSI, BER, and Cell Neighbor for reporting connection issues to M2X

Dependencies:   WncControllerK64F

Committer:
JMF
Date:
Thu Nov 17 16:13:29 2016 +0000
Revision:
18:198e9b0acf11
Parent:
12:0071cb144c7a
Updates to mbed os resulted in mutex.h going away and rtos.h needed to be used; This fixes the Mutex typedef failure.  Also cast data buffers from 'char *' to (const std::uint8_t*) to conform with Fred's changes in WncController

Who changed what in which revision?

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