/* * Write at most 'len' characters */ int mbedtls_mediatek_send( void *ctx, const unsigned char *buf, size_t len ) { int ret; int fd = ((mbedtls_net_context *) ctx)->fd; if( fd < 0 ) return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); ret = (int) vm_send(fd, buf, len, 0); if( ret < 0 ) { if( net_would_block( ctx ) != 0 ) return( MBEDTLS_ERR_SSL_WANT_WRITE ); #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ !defined(EFI32) if( WSAGetLastError() == WSAECONNRESET ) return( MBEDTLS_ERR_NET_CONN_RESET ); #else if( errno == EPIPE || errno == ECONNRESET ) return( MBEDTLS_ERR_NET_CONN_RESET ); if( errno == EINTR ) return( MBEDTLS_ERR_SSL_WANT_WRITE ); #endif return( MBEDTLS_ERR_NET_SEND_FAILED ); } return( ret ); }
/* * Write at most 'len' characters */ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ) { int ret; int fd = ((mbedtls_net_context *) ctx)->fd; int error = 0; if ( fd < 0 ) { return ( MBEDTLS_ERR_NET_INVALID_CONTEXT ); } ret = (int) write( fd, buf, len ); if ( ret < 0 ) { if ( net_would_block( ctx, &error ) != 0 ) { return ( MBEDTLS_ERR_SSL_WANT_WRITE ); } if ( error == EPIPE || error == ECONNRESET ) { return ( MBEDTLS_ERR_NET_CONN_RESET ); } if ( error == EINTR ) { return ( MBEDTLS_ERR_SSL_WANT_WRITE ); } return ( MBEDTLS_ERR_NET_SEND_FAILED ); } return ( ret ); }
/* * Write at most 'len' characters */ int net_send( void *ctx, const unsigned char *buf, size_t len ) { int fd = *((int *) ctx); int ret = (int) write( fd, buf, len ); if( ret < 0 ) { if( net_would_block( fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_WRITE ); #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ !defined(EFI32) if( WSAGetLastError() == WSAECONNRESET ) return( POLARSSL_ERR_NET_CONN_RESET ); #else if( errno == EPIPE || errno == ECONNRESET ) return( POLARSSL_ERR_NET_CONN_RESET ); if( errno == EINTR ) return( POLARSSL_ERR_NET_WANT_WRITE ); #endif return( POLARSSL_ERR_NET_SEND_FAILED ); } return( ret ); }
/* * Read at most 'len' characters */ int net_recv( void *ctx, unsigned char *buf, size_t len ) { int fd = *((int *) ctx); int ret = read( fd, buf, len ); if( ret < 0 ) { if( net_would_block( fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_READ ); #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ !defined(EFI32) if( WSAGetLastError() == WSAECONNRESET ) return( POLARSSL_ERR_NET_CONN_RESET ); #else #ifdef ERRNO if( errno == EPIPE || errno == ECONNRESET ) return( POLARSSL_ERR_NET_CONN_RESET ); if( errno == EINTR ) return( POLARSSL_ERR_NET_WANT_READ ); #endif #endif return( POLARSSL_ERR_NET_RECV_FAILED ); } return( ret ); }
/* * Read at most 'len' characters and write to buf. */ static int recv_custom( void *ctx, unsigned char *buf, size_t len ) { int ret; #if SOCKET_COMMUNICATION int fd = *((int *) ctx); if( fd < 0 ) return( POLARSSL_ERR_NET_SOCKET_FAILED ); ret = (int) read( fd, buf, len ); #else ((void) ctx); ((void) len); if ( ((*recv_off + len) <= BUF_SIZE) && memcpy( buf, &shared_buf[*recv_off], len ) ) { *recv_off += len; if( *recv_off == *send_off ) { /* * Done copying buffer. * Reset offsets for next calls of send and rcv functions. */ *recv_off = 0; *send_off = 0; } /* Imitate the return value of read(2). */ ret = len; } else { ret = -1; } #endif #if SOCKET_COMMUNICATION if( ret < 0 ) { if( net_would_block( fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_READ ); #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ !defined(EFI32) if( WSAGetLastError() == WSAECONNRESET ) return( POLARSSL_ERR_NET_CONN_RESET ); #else if( errno == EPIPE || errno == ECONNRESET ) return( POLARSSL_ERR_NET_CONN_RESET ); if( errno == EINTR ) return( POLARSSL_ERR_NET_WANT_READ ); #endif return( POLARSSL_ERR_NET_RECV_FAILED ); } #endif return( ret ); }
/* * Accept a connection from a remote client */ int net_accept( int bind_fd, int *client_fd, void *client_ip ) { #if defined(POLARSSL_HAVE_IPV6) struct sockaddr_storage client_addr; #else struct sockaddr_in client_addr; #endif #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ defined(_SOCKLEN_T_DECLARED) socklen_t n = (socklen_t) sizeof( client_addr ); #else int n = (int) sizeof( client_addr ); #endif *client_fd = (int) accept( bind_fd, (struct sockaddr *) &client_addr, &n ); if( *client_fd < 0 ) { if( net_would_block( *client_fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_READ ); return( POLARSSL_ERR_NET_ACCEPT_FAILED ); } if( client_ip != NULL ) { #if defined(POLARSSL_HAVE_IPV6) if( client_addr.ss_family == AF_INET ) { struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; memcpy( client_ip, &addr4->sin_addr.s_addr, sizeof( addr4->sin_addr.s_addr ) ); } else { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; memcpy( client_ip, &addr6->sin6_addr.s6_addr, sizeof( addr6->sin6_addr.s6_addr ) ); } #else memcpy( client_ip, &client_addr.sin_addr.s_addr, sizeof( client_addr.sin_addr.s_addr ) ); #endif /* POLARSSL_HAVE_IPV6 */ } return( 0 ); }
int CConsoleNetConnection::Update() { if(State() == NET_CONNSTATE_ONLINE) { if((int)(sizeof(m_aBuffer)) <= m_BufferOffset) { m_State = NET_CONNSTATE_ERROR; str_copy(m_aErrorString, "too weak connection (out of buffer)", sizeof(m_aErrorString)); return -1; } int Bytes = net_tcp_recv(m_Socket, m_aBuffer+m_BufferOffset, (int)(sizeof(m_aBuffer))-m_BufferOffset); if(Bytes > 0) { m_BufferOffset += Bytes; } else if(Bytes < 0) { if(net_would_block()) // no data received return 0; m_State = NET_CONNSTATE_ERROR; // error str_copy(m_aErrorString, "connection failure", sizeof(m_aErrorString)); return -1; } else { m_State = NET_CONNSTATE_ERROR; str_copy(m_aErrorString, "remote end closed the connection", sizeof(m_aErrorString)); return -1; } } return 0; }
/* * Write at most 'len' characters to shared buffer or file. * Multiple sends can occur before a receive; therefore, maintain an * offset. * Also, write content of file to shared buffer, if desired (determined * by command-line options). */ static int send_custom( void *ctx, const unsigned char *buf, size_t len ) { int ret; #if SOCKET_COMMUNICATION int fd = *((int *) ctx); if( fd < 0 ) return( POLARSSL_ERR_NET_SOCKET_FAILED ); #else ((void) ctx); #endif /* Read packet from file or write packet to file */ if( packet_count == packet_in_num ) { FILE *in_file; #if !SOCKET_COMMUNICATION size_t rlen; #endif if( !packet_in_file ) { polarssl_fprintf( stderr, "Packet input file not specified!\n" ); exit(1); } /* Read packet from file, ignoring buf */ in_file = fopen( packet_in_file, "rb" ); if( !in_file ) { perror( "Unable to open packet input file" ); exit( 1 ); } /* Write packet to socket/buffer. */ #if SOCKET_COMMUNICATION ret = (int) write( fd, buf, len ); #else rlen = fread( shared_buf, sizeof(shared_buf[0]), BUF_SIZE, in_file ); #endif if ( ferror( in_file ) ) { perror( "Unable to read packet input file" ); exit( 1 ); } #if !SOCKET_COMMUNICATION else { *send_off += rlen; ret = rlen; } #endif fclose( in_file ); } else { /* Write packet to socket/buffer. */ #if SOCKET_COMMUNICATION ret = (int) write( fd, buf, len ); #else if ( (len <= BUF_SIZE) && memcpy( shared_buf, buf, len ) ) { *send_off += len; ret = len; } else { ret = -1; } #endif if( packet_in_num == 0 ) { char out_filename[100]; FILE *out_file; /* Write packet to file. */ snprintf( out_filename, sizeof(out_filename), "%s%zd", PACKET_FILE_PREFIX, packet_count ); out_file = fopen( out_filename, "wb" ); fwrite( buf, sizeof(char), len, out_file ); fclose( out_file ); } } packet_count++; #if SOCKET_COMMUNICATION if( ret < 0 ) { if( net_would_block( fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_WRITE ); #if( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ !defined(EFI32) if( WSAGetLastError() == WSAECONNRESET ) return( POLARSSL_ERR_NET_CONN_RESET ); #else if( errno == EPIPE || errno == ECONNRESET ) return( POLARSSL_ERR_NET_CONN_RESET ); if( errno == EINTR ) return( POLARSSL_ERR_NET_WANT_WRITE ); #endif return( POLARSSL_ERR_NET_SEND_FAILED ); } #endif return( ret ); }
/* * Accept a connection from a remote client */ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, mbedtls_net_context *client_ctx, void *client_ip, size_t buf_size, size_t *ip_len ) { int ret; int type; struct sockaddr_storage client_addr; #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) socklen_t n = (socklen_t) sizeof( client_addr ); socklen_t type_len = (socklen_t) sizeof( type ); #else int n = (int) sizeof( client_addr ); int type_len = (int) sizeof( type ); #endif /* Is this a TCP or UDP socket? */ if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE, (void *) &type, &type_len ) != 0 || ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) { return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); } if( type == SOCK_STREAM ) { /* TCP: actual accept() */ ret = client_ctx->fd = (int) accept( bind_ctx->fd, (struct sockaddr *) &client_addr, &n ); } else { /* UDP: wait for a message, but keep it in the queue */ char buf[1] = { 0 }; ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, (struct sockaddr *) &client_addr, &n ); #if defined(_WIN32) if( ret == SOCKET_ERROR && WSAGetLastError() == WSAEMSGSIZE ) { /* We know buf is too small, thanks, just peeking here */ ret = 0; } #endif } if( ret < 0 ) { if( net_would_block( bind_ctx ) != 0 ) return( MBEDTLS_ERR_SSL_WANT_READ ); return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); } /* UDP: hijack the listening socket to communicate with the client, * then bind a new socket to accept new connections */ if( type != SOCK_STREAM ) { struct sockaddr_storage local_addr; int one = 1; if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); client_ctx->fd = bind_ctx->fd; bind_ctx->fd = -1; /* In case we exit early */ n = sizeof( struct sockaddr_storage ); if( getsockname( client_ctx->fd, (struct sockaddr *) &local_addr, &n ) != 0 || ( bind_ctx->fd = (int) socket( local_addr.ss_family, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 || setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &one, sizeof( one ) ) != 0 ) { return( MBEDTLS_ERR_NET_SOCKET_FAILED ); } if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) { return( MBEDTLS_ERR_NET_BIND_FAILED ); } } if( client_ip != NULL ) { if( client_addr.ss_family == AF_INET ) { struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; *ip_len = sizeof( addr4->sin_addr.s_addr ); if( buf_size < *ip_len ) return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); } else { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; *ip_len = sizeof( addr6->sin6_addr.s6_addr ); if( buf_size < *ip_len ) return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len); } } return( 0 ); }
/* * Accept a connection from a remote client */ int net_accept( int bind_fd, int *client_fd, void *client_ip ) { int ret; int type; #if defined(POLARSSL_HAVE_IPV6) struct sockaddr_storage client_addr; #else struct sockaddr_in client_addr; #endif #if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ defined(_SOCKLEN_T_DECLARED) socklen_t n = (socklen_t) sizeof( client_addr ); socklen_t type_len = (socklen_t) sizeof( type ); #else int n = (int) sizeof( client_addr ); int type_len = (int) sizeof( type ); #endif /* Is this a TCP or UDP socket? */ if( getsockopt( bind_fd, SOL_SOCKET, SO_TYPE, &type, &type_len ) != 0 || ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) { return( POLARSSL_ERR_NET_ACCEPT_FAILED ); } if( type == SOCK_STREAM ) { /* TCP: actual accept() */ ret = *client_fd = (int) accept( bind_fd, (struct sockaddr *) &client_addr, &n ); } else { /* UDP: wait for a message, but keep it in the queue */ char buf[1] = { 0 }; ret = recvfrom( bind_fd, buf, sizeof( buf ), MSG_PEEK, (struct sockaddr *) &client_addr, &n ); } if( ret < 0 ) { if( net_would_block( bind_fd ) != 0 ) return( POLARSSL_ERR_NET_WANT_READ ); return( POLARSSL_ERR_NET_ACCEPT_FAILED ); } /* UDP: hijack the listening socket for communicating with the client */ if( type != SOCK_STREAM ) { if( connect( bind_fd, (struct sockaddr *) &client_addr, n ) != 0 ) return( POLARSSL_ERR_NET_ACCEPT_FAILED ); *client_fd = bind_fd; } if( client_ip != NULL ) { #if defined(POLARSSL_HAVE_IPV6) if( client_addr.ss_family == AF_INET ) { struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; memcpy( client_ip, &addr4->sin_addr.s_addr, sizeof( addr4->sin_addr.s_addr ) ); } else { struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; memcpy( client_ip, &addr6->sin6_addr.s6_addr, sizeof( addr6->sin6_addr.s6_addr ) ); } #else memcpy( client_ip, &client_addr.sin_addr.s_addr, sizeof( client_addr.sin_addr.s_addr ) ); #endif /* POLARSSL_HAVE_IPV6 */ } return( 0 ); }
/* * Read at most 'len' characters, blocking for at most 'timeout' ms */ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, uint32_t timeout ) { int ret; struct timeval tv; fd_set read_fds; int fd = ((mbedtls_net_context *) ctx)->fd; if( fd < 0 ) return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); FD_ZERO( &read_fds ); FD_SET( fd, &read_fds ); tv.tv_sec = timeout / 1000; tv.tv_usec = ( timeout % 1000 ) * 1000; #if defined(__CELLOS_LV2__) ret = socketselect(fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv); #elif defined(VITA) extern int retro_epoll_fd; SceNetEpollEvent ev = {0}; ev.events = SCE_NET_EPOLLIN | SCE_NET_EPOLLHUP; ev.data.fd = fd + 1; if((sceNetEpollControl(retro_epoll_fd, SCE_NET_EPOLL_CTL_ADD, fd + 1, &ev))) { int ret = sceNetEpollWait(retro_epoll_fd, &ev, 1, 0); sceNetEpollControl(retro_epoll_fd, SCE_NET_EPOLL_CTL_DEL, fd + 1, NULL); #else ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv ); #endif /* Zero fds ready means we timed out */ if( ret == 0 ) return( MBEDTLS_ERR_SSL_TIMEOUT ); if( ret < 0 ) { #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ !defined(EFI32) if( WSAGetLastError() == WSAEINTR ) return( MBEDTLS_ERR_SSL_WANT_READ ); #else if( errno == EINTR ) return( MBEDTLS_ERR_SSL_WANT_READ ); #endif return( MBEDTLS_ERR_NET_RECV_FAILED ); } /* This call will not block */ return( mbedtls_net_recv( ctx, buf, len ) ); } /* * Write at most 'len' characters */ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ) { int ret; int fd = ((mbedtls_net_context *) ctx)->fd; if( fd < 0 ) return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); ret = (int) write( fd, buf, len ); if( ret < 0 ) { if( net_would_block( ctx ) != 0 ) return( MBEDTLS_ERR_SSL_WANT_WRITE ); #if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ !defined(EFI32) if( WSAGetLastError() == WSAECONNRESET ) return( MBEDTLS_ERR_NET_CONN_RESET ); #else if( errno == EPIPE || errno == ECONNRESET ) return( MBEDTLS_ERR_NET_CONN_RESET ); if( errno == EINTR ) return( MBEDTLS_ERR_SSL_WANT_WRITE ); #endif return( MBEDTLS_ERR_NET_SEND_FAILED ); } return( ret ); }
/* * Accept a connection from a remote client */ int mbedtls_net_accept( mbedtls_net_context *bind_ctx, mbedtls_net_context *client_ctx, void *client_ip, size_t buf_size, size_t *ip_len ) { int ret; int type; struct sockaddr_in client_addr; socklen_t n = (socklen_t) sizeof( client_addr ); socklen_t type_len = (socklen_t) sizeof( type ); /* Is this a TCP or UDP socket? */ if ( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE, (void *) &type, (socklen_t *) &type_len ) != 0 || ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) { return ( MBEDTLS_ERR_NET_ACCEPT_FAILED ); } if ( type == SOCK_STREAM ) { /* TCP: actual accept() */ ret = client_ctx->fd = (int) accept( bind_ctx->fd, (struct sockaddr *) &client_addr, &n ); } else { /* UDP: wait for a message, but keep it in the queue */ char buf[1] = { 0 }; ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, (struct sockaddr *) &client_addr, &n ); } if ( ret < 0 ) { if ( net_would_block( bind_ctx, NULL ) != 0 ) { return ( MBEDTLS_ERR_SSL_WANT_READ ); } return ( MBEDTLS_ERR_NET_ACCEPT_FAILED ); } /* UDP: hijack the listening socket to communicate with the client, * then bind a new socket to accept new connections */ if ( type != SOCK_STREAM ) { struct sockaddr_in local_addr; int one = 1; if ( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) { return ( MBEDTLS_ERR_NET_ACCEPT_FAILED ); } client_ctx->fd = bind_ctx->fd; bind_ctx->fd = -1; /* In case we exit early */ n = sizeof( struct sockaddr_in ); if ( getsockname( client_ctx->fd, (struct sockaddr *) &local_addr, &n ) != 0 || ( bind_ctx->fd = (int) socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 || setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &one, sizeof( one ) ) != 0 ) { return ( MBEDTLS_ERR_NET_SOCKET_FAILED ); } if ( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) { return ( MBEDTLS_ERR_NET_BIND_FAILED ); } } if ( client_ip != NULL ) { struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; *ip_len = sizeof( addr4->sin_addr.s_addr ); if ( buf_size < *ip_len ) { return ( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); } memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); } return ( 0 ); }