nodemcu-firmware/app/mbedtls/platform/mbedtls_net.c

314 lines
7.5 KiB
C
Raw Permalink Normal View History

/*
* TCP/IP or UDP/IP networking functions
* modified for LWIP support on ESP8266
*
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
* Additions Copyright (C) 2015 Angus Gratton
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This file is part of mbed TLS (https://tls.mbed.org)
*/
#include "mbedtls/config.h"
#if defined(MBEDTLS_NET_C)
#include "mbedtls/net_sockets.h"
#include <string.h>
//
#include <sys/types.h>
#include <sys/socket.h>
//#include <sys/time.h>
#include <unistd.h>
#include "lwip/netdb.h"
#include <errno.h>
//
#include <stdlib.h>
#include <stdio.h>
//
#include <time.h>
//
#include <stdint.h>
/*
* Prepare for using the sockets interface
*/
static int net_prepare( void )
{
return( 0 );
}
/*
* Initialize a context
*/
void mbedtls_net_init( mbedtls_net_context *ctx )
{
ctx->fd = -1;
}
/*
* Initiate a TCP connection with host:port and the given protocol
*/
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
{
int ret;
uint32 ports = getul((char*)port);
struct sockaddr_in client_addr;
struct sockaddr_in server_addr;
if( ( ret = net_prepare() ) != 0 )
return( ret );
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = htons(IPADDR_ANY);
client_addr.sin_port = htons(0);
ctx->fd = socket(AF_INET, SOCK_STREAM,IPPROTO_TCP);
if( ctx->fd < 0 ){
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
os_printf("Create Socket Failed!\n");
goto mbedtls_error;
}
if (bind(ctx->fd, (struct sockaddr*)&client_addr,sizeof(client_addr))) {
ret = MBEDTLS_ERR_NET_BIND_FAILED;
os_printf("Client Bind Port Failed!\n");
goto mbedtls_error;
}
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = ipaddr_addr(host);
server_addr.sin_port = htons(ports);
ret = connect(ctx->fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
if (ret < 0){
ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
os_printf("Can Not Connect To!\n");
}
mbedtls_error:
if (ret < 0)
close( ctx->fd );
return( ret );
}
Networking rampage and accumulated fixes (#3060) * espconn: remove unused espconn code, take 1 This is the easiest part of https://github.com/nodemcu/nodemcu-firmware/issues/3004 . It removes a bunch of functions that were never called in our tree. * espconn: De-orbit espconn_gethostbyname Further work on https://github.com/nodemcu/nodemcu-firmware/issues/3004 While here, remove `mqtt`'s charming DNS-retry logic (which is neither shared with nor duplicated in other modules) and update its :connect() return value behavior and documentation. * espconn: remove scary global pktinfo A write-only global! How about that. * net: remove deprecated methods All the TLS stuff moved over there a long time ago, and net_createUDPSocket should just do what it says on the tin. * espconn_secure: remove ESPCONN_SERVER support We can barely function as a TLS client; being a TLS server seems like a real stretch. This code was never called from Lua anyway. * espconn_secure: more code removal * espconn_secure: simplify ssl options structure There is nothing "ssl_packet" about this structure. Get rid of the terrifying "pbuffer" pointer. Squash two structure types together and eliminate an unused field. * espconn_secure: refactor mbedtls_msg_info_load Split out espconn_mbedtls_parse, which we can use as part of our effort towards addressing https://github.com/nodemcu/nodemcu-firmware/issues/3032 * espconn_secure: introduce TLS cert/key callbacks The new feature part of https://github.com/nodemcu/nodemcu-firmware/issues/3032 Subsequent work will remove the old mechanism. * tls: add deprecation warnings * luacheck: net.ifinfo is a thing now * tls: remove use of espconn->reverse * mqtt: stop using espconn->reverse Instead, just place the espconn structure itself at the top of the user data. This enlarges the structure somewhat but removes one more layer of dynamic heap usage and NULL checks. While here, simplify the code a bit. * mqtt: remove redundant pointer to connect_info Everywhere we have the mqtt_state_t we also have the lmqtt_userdata. * mqtt: doc fixes * mqtt: note bug * tls: allow :on(...,nil) to unregister a callback
2020-04-07 14:06:27 +02:00
#if 0 // NodeMCU does not support being a TLS server
/*
* Create a listening socket on bind_ip:port
*/
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
{
int ret;
int protocol = 0;
int sock_type = 0;
uint32 ports = getul((char*)port);
struct sockaddr_in server_addr;
if( ( ret = net_prepare() ) != 0 )
return( ret );
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(IPADDR_ANY);
server_addr.sin_port = htons(ports);
protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
sock_type = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
ctx->fd = socket(AF_INET, sock_type, protocol);
if( ctx->fd < 0 ){
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
os_printf("Create Socket Failed!\n");
goto mbedtls_error;
}
ret = bind(ctx->fd, (struct sockaddr*)&server_addr,sizeof(server_addr));
if (ret != 0){
ret = MBEDTLS_ERR_NET_BIND_FAILED;
os_printf("Server Bind Port Failed!\n");
goto mbedtls_error;
}
if (proto == MBEDTLS_NET_PROTO_TCP){
ret = listen(ctx->fd, MBEDTLS_ERR_NET_LISTEN_FAILED);
if (ret != 0){
ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
goto mbedtls_error;
}
}
ret = 0;
mbedtls_error:
if (ret < 0)
close( ctx->fd );
return( ret );
}
Networking rampage and accumulated fixes (#3060) * espconn: remove unused espconn code, take 1 This is the easiest part of https://github.com/nodemcu/nodemcu-firmware/issues/3004 . It removes a bunch of functions that were never called in our tree. * espconn: De-orbit espconn_gethostbyname Further work on https://github.com/nodemcu/nodemcu-firmware/issues/3004 While here, remove `mqtt`'s charming DNS-retry logic (which is neither shared with nor duplicated in other modules) and update its :connect() return value behavior and documentation. * espconn: remove scary global pktinfo A write-only global! How about that. * net: remove deprecated methods All the TLS stuff moved over there a long time ago, and net_createUDPSocket should just do what it says on the tin. * espconn_secure: remove ESPCONN_SERVER support We can barely function as a TLS client; being a TLS server seems like a real stretch. This code was never called from Lua anyway. * espconn_secure: more code removal * espconn_secure: simplify ssl options structure There is nothing "ssl_packet" about this structure. Get rid of the terrifying "pbuffer" pointer. Squash two structure types together and eliminate an unused field. * espconn_secure: refactor mbedtls_msg_info_load Split out espconn_mbedtls_parse, which we can use as part of our effort towards addressing https://github.com/nodemcu/nodemcu-firmware/issues/3032 * espconn_secure: introduce TLS cert/key callbacks The new feature part of https://github.com/nodemcu/nodemcu-firmware/issues/3032 Subsequent work will remove the old mechanism. * tls: add deprecation warnings * luacheck: net.ifinfo is a thing now * tls: remove use of espconn->reverse * mqtt: stop using espconn->reverse Instead, just place the espconn structure itself at the top of the user data. This enlarges the structure somewhat but removes one more layer of dynamic heap usage and NULL checks. While here, simplify the code a bit. * mqtt: remove redundant pointer to connect_info Everywhere we have the mqtt_state_t we also have the lmqtt_userdata. * mqtt: doc fixes * mqtt: note bug * tls: allow :on(...,nil) to unregister a callback
2020-04-07 14:06:27 +02:00
#endif
/*
* Check if the requested operation would be blocking on a non-blocking socket
* and thus 'failed' with a negative return value.
*
* Note: on a blocking socket this function always returns 0!
*/
static int net_would_block( const mbedtls_net_context *ctx )
{
return( 0 );
}
Networking rampage and accumulated fixes (#3060) * espconn: remove unused espconn code, take 1 This is the easiest part of https://github.com/nodemcu/nodemcu-firmware/issues/3004 . It removes a bunch of functions that were never called in our tree. * espconn: De-orbit espconn_gethostbyname Further work on https://github.com/nodemcu/nodemcu-firmware/issues/3004 While here, remove `mqtt`'s charming DNS-retry logic (which is neither shared with nor duplicated in other modules) and update its :connect() return value behavior and documentation. * espconn: remove scary global pktinfo A write-only global! How about that. * net: remove deprecated methods All the TLS stuff moved over there a long time ago, and net_createUDPSocket should just do what it says on the tin. * espconn_secure: remove ESPCONN_SERVER support We can barely function as a TLS client; being a TLS server seems like a real stretch. This code was never called from Lua anyway. * espconn_secure: more code removal * espconn_secure: simplify ssl options structure There is nothing "ssl_packet" about this structure. Get rid of the terrifying "pbuffer" pointer. Squash two structure types together and eliminate an unused field. * espconn_secure: refactor mbedtls_msg_info_load Split out espconn_mbedtls_parse, which we can use as part of our effort towards addressing https://github.com/nodemcu/nodemcu-firmware/issues/3032 * espconn_secure: introduce TLS cert/key callbacks The new feature part of https://github.com/nodemcu/nodemcu-firmware/issues/3032 Subsequent work will remove the old mechanism. * tls: add deprecation warnings * luacheck: net.ifinfo is a thing now * tls: remove use of espconn->reverse * mqtt: stop using espconn->reverse Instead, just place the espconn structure itself at the top of the user data. This enlarges the structure somewhat but removes one more layer of dynamic heap usage and NULL checks. While here, simplify the code a bit. * mqtt: remove redundant pointer to connect_info Everywhere we have the mqtt_state_t we also have the lmqtt_userdata. * mqtt: doc fixes * mqtt: note bug * tls: allow :on(...,nil) to unregister a callback
2020-04-07 14:06:27 +02:00
#if 0 // NodeMCU does not support being a TLS server
/*
* 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 );
client_ctx->fd = (int) accept( bind_ctx->fd,(struct sockaddr *) &client_addr, &n );
if (client_ctx->fd < 0){
ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
os_printf("Create Socket Failed!\n");
goto mbedtls_error;
}
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 ){
ret = MBEDTLS_ERR_NET_BUFFER_TOO_SMALL;
os_printf("Create Socket Failed!\n");
goto mbedtls_error;
}
memcpy(client_ip, &addr4->sin_addr.s_addr, *ip_len);
}
ret = 0;
mbedtls_error:
if (ret < 0)
close( client_ctx->fd );
return( ret );
return( 0 );
}
Networking rampage and accumulated fixes (#3060) * espconn: remove unused espconn code, take 1 This is the easiest part of https://github.com/nodemcu/nodemcu-firmware/issues/3004 . It removes a bunch of functions that were never called in our tree. * espconn: De-orbit espconn_gethostbyname Further work on https://github.com/nodemcu/nodemcu-firmware/issues/3004 While here, remove `mqtt`'s charming DNS-retry logic (which is neither shared with nor duplicated in other modules) and update its :connect() return value behavior and documentation. * espconn: remove scary global pktinfo A write-only global! How about that. * net: remove deprecated methods All the TLS stuff moved over there a long time ago, and net_createUDPSocket should just do what it says on the tin. * espconn_secure: remove ESPCONN_SERVER support We can barely function as a TLS client; being a TLS server seems like a real stretch. This code was never called from Lua anyway. * espconn_secure: more code removal * espconn_secure: simplify ssl options structure There is nothing "ssl_packet" about this structure. Get rid of the terrifying "pbuffer" pointer. Squash two structure types together and eliminate an unused field. * espconn_secure: refactor mbedtls_msg_info_load Split out espconn_mbedtls_parse, which we can use as part of our effort towards addressing https://github.com/nodemcu/nodemcu-firmware/issues/3032 * espconn_secure: introduce TLS cert/key callbacks The new feature part of https://github.com/nodemcu/nodemcu-firmware/issues/3032 Subsequent work will remove the old mechanism. * tls: add deprecation warnings * luacheck: net.ifinfo is a thing now * tls: remove use of espconn->reverse * mqtt: stop using espconn->reverse Instead, just place the espconn structure itself at the top of the user data. This enlarges the structure somewhat but removes one more layer of dynamic heap usage and NULL checks. While here, simplify the code a bit. * mqtt: remove redundant pointer to connect_info Everywhere we have the mqtt_state_t we also have the lmqtt_userdata. * mqtt: doc fixes * mqtt: note bug * tls: allow :on(...,nil) to unregister a callback
2020-04-07 14:06:27 +02:00
#endif
/*
* Set the socket blocking or non-blocking
*/
int mbedtls_net_set_block( mbedtls_net_context *ctx )
{
return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) & ~O_NONBLOCK ) );
}
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
{
return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) | O_NONBLOCK ) );
}
/*
* Read at most 'len' characters
*/
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
{
int ret;
int fd = ((mbedtls_net_context *) ctx)->fd;
if( fd < 0 )
return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
// os_printf("mbedtls_net_recv need %d\n", len);
ret = (int) read( fd, buf, len );
if( ret < 0 )
{
if( net_would_block( ctx ) != 0 )
return( MBEDTLS_ERR_SSL_WANT_READ );
return( MBEDTLS_ERR_NET_RECV_FAILED );
}
// os_printf("mbedtls_net_recv get %d\n", ret);
if (ret == 0)
return( MBEDTLS_ERR_SSL_WANT_READ );
return( ret );
}
/*
* 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 );
/* 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 );
// os_printf("mbedtls_net_send need %d\n", len);
ret = (int) write( fd, buf, len );
if( ret < 0 )
{
if( net_would_block( ctx ) != 0 )
return( MBEDTLS_ERR_SSL_WANT_WRITE );
}
// os_printf("mbedtls_net_send write %d\n", ret);
if (ret == 0)
return( MBEDTLS_ERR_SSL_WANT_WRITE );
return( ret );
}
/*
* Gracefully close the connection
*/
void mbedtls_net_free( mbedtls_net_context *ctx )
{
if( ctx->fd == -1 )
return;
close( ctx->fd );
ctx->fd = -1;
}
#endif /* MBEDTLS_NET_C */