diff --git a/hal/inc/hal_socket.h b/hal/inc/hal_socket.h index c55ad19e..3b5490a5 100644 --- a/hal/inc/hal_socket.h +++ b/hal/inc/hal_socket.h @@ -1,7 +1,7 @@ /* * socket_hal.h * - * Copyright 2013-2022 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of Platform Abstraction Layer (libpal) * for libiec61850, libmms, and lib60870. diff --git a/hal/inc/hal_time.h b/hal/inc/hal_time.h index bf7df781..b3e49abf 100644 --- a/hal/inc/hal_time.h +++ b/hal/inc/hal_time.h @@ -1,7 +1,7 @@ /* * time.c * - * Copyright 2013-2022 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of Platform Abstraction Layer (libpal) * for libiec61850, libmms, and lib60870. @@ -68,6 +68,22 @@ Hal_getTimeInNs(void); PAL_API bool Hal_setTimeInNs(nsSinceEpoch nsTime); +/** + * Get the monotonic time or system tick time in ms + * + * \return the system time with millisecond resolution. + */ +PAL_API msSinceEpoch +Hal_getMonotonicTimeInMs(void); + +/** + * Get the monotonic time or system tick in nanoseconds. + * + * \return the system time with nanosecond resolution. + */ +PAL_API nsSinceEpoch +Hal_getMonotonicTimeInNs(void); + /*! @} */ /*! @} */ diff --git a/hal/memory/lib_memory.c b/hal/memory/lib_memory.c index 74fde5b4..ec86b75d 100644 --- a/hal/memory/lib_memory.c +++ b/hal/memory/lib_memory.c @@ -65,3 +65,4 @@ Memory_free(void* memb) { free(memb); } + diff --git a/hal/socket/bsd/socket_bsd.c b/hal/socket/bsd/socket_bsd.c index 1d928559..009b7704 100644 --- a/hal/socket/bsd/socket_bsd.c +++ b/hal/socket/bsd/socket_bsd.c @@ -1,33 +1,33 @@ /* * socket_bsd.c * - * Copyright 2013-2021 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of Platform Abstraction Layer (libpal) * for libiec61850, libmms, and lib60870. */ #include "hal_socket.h" -#include -#include -#include #include -#include -#include -#include -#include #include -#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include // required for TCP keepalive -#include #include +#include -#include "linked_list.h" #include "hal_thread.h" #include "lib_memory.h" +#include "linked_list.h" #ifndef DEBUG_SOCKET #define DEBUG_SOCKET 0 @@ -41,22 +41,26 @@ #define MSG_NOSIGNAL 0 #endif -struct sSocket { +struct sSocket +{ int fd; uint32_t connectTimeout; }; -struct sServerSocket { +struct sServerSocket +{ int fd; int backLog; }; -struct sUdpSocket { +struct sUdpSocket +{ int fd; int namespace; /* IPv4: AF_INET; IPv6: AF_INET6 */ }; -struct sHandleSet { +struct sHandleSet +{ LinkedList sockets; bool pollfdIsUpdated; struct pollfd* fds; @@ -66,9 +70,10 @@ struct sHandleSet { HandleSet Handleset_new(void) { - HandleSet self = (HandleSet) GLOBAL_MALLOC(sizeof(struct sHandleSet)); + HandleSet self = (HandleSet)GLOBAL_MALLOC(sizeof(struct sHandleSet)); - if (self) { + if (self) + { self->sockets = LinkedList_create(); self->pollfdIsUpdated = false; self->fds = NULL; @@ -81,8 +86,10 @@ Handleset_new(void) void Handleset_reset(HandleSet self) { - if (self) { - if (self->sockets) { + if (self) + { + if (self->sockets) + { LinkedList_destroyStatic(self->sockets); self->sockets = LinkedList_create(); self->pollfdIsUpdated = false; @@ -93,7 +100,8 @@ Handleset_reset(HandleSet self) void Handleset_addSocket(HandleSet self, const Socket sock) { - if (self != NULL && sock != NULL && sock->fd != -1) { + if (self != NULL && sock != NULL && sock->fd != -1) + { LinkedList_add(self->sockets, sock); self->pollfdIsUpdated = false; } @@ -102,7 +110,8 @@ Handleset_addSocket(HandleSet self, const Socket sock) void Handleset_removeSocket(HandleSet self, const Socket sock) { - if (self && self->sockets && sock) { + if (self && self->sockets && sock) + { LinkedList_remove(self->sockets, sock); self->pollfdIsUpdated = false; } @@ -112,8 +121,10 @@ int Handleset_waitReady(HandleSet self, unsigned int timeoutMs) { /* check if pollfd array is updated */ - if (self->pollfdIsUpdated == false) { - if (self->fds) { + if (self->pollfdIsUpdated == false) + { + if (self->fds) + { GLOBAL_FREEMEM(self->fds); self->fds = NULL; } @@ -124,13 +135,16 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) int i; - for (i = 0; i < self->nfds; i++) { + for (i = 0; i < self->nfds; i++) + { LinkedList sockElem = LinkedList_get(self->sockets, i); - if (sockElem) { - Socket sock = (Socket) LinkedList_getData(sockElem); + if (sockElem) + { + Socket sock = (Socket)LinkedList_getData(sockElem); - if (sock) { + if (sock) + { self->fds[i].fd = sock->fd; self->fds[i].events = POLL_IN; } @@ -140,17 +154,20 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) self->pollfdIsUpdated = true; } - if (self->fds && self->nfds > 0) { + if (self->fds && self->nfds > 0) + { int result = poll(self->fds, self->nfds, timeoutMs); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: poll error (errno: %i)\n", errno); } return result; } - else { + else + { /* there is no socket to wait for */ return 0; } @@ -159,7 +176,8 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) void Handleset_destroy(HandleSet self) { - if (self) { + if (self) + { if (self->sockets) LinkedList_destroyStatic(self->sockets); @@ -197,18 +215,20 @@ static bool prepareAddress(const char* address, int port, struct sockaddr_in* sockaddr) { - memset((char *) sockaddr , 0, sizeof(struct sockaddr_in)); + memset((char*)sockaddr, 0, sizeof(struct sockaddr_in)); - if (address != NULL) { - struct hostent *server; - server = gethostbyname(address); + if (address != NULL) + { + struct hostent* server; + server = gethostbyname(address); - if (server == NULL) return false; + if (server == NULL) + return false; - memcpy((char *) &sockaddr->sin_addr.s_addr, (char *) server->h_addr, server->h_length); - } - else - sockaddr->sin_addr.s_addr = htonl(INADDR_ANY); + memcpy((char*)&sockaddr->sin_addr.s_addr, (char*)server->h_addr, server->h_length); + } + else + sockaddr->sin_addr.s_addr = htonl(INADDR_ANY); sockaddr->sin_family = AF_INET; sockaddr->sin_port = htons(port); @@ -228,7 +248,7 @@ activateTcpNoDelay(Socket self) { /* activate TCP_NODELAY option - packets will be sent immediately */ int flag = 1; - setsockopt(self->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); + setsockopt(self->fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int)); } ServerSocket @@ -238,27 +258,31 @@ TcpServerSocket_create(const char* address, int port) int fd; - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) { + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) + { struct sockaddr_in serverAddress; - if (!prepareAddress(address, port, &serverAddress)) { + if (!prepareAddress(address, port, &serverAddress)) + { close(fd); return NULL; } int optionReuseAddr = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &optionReuseAddr, sizeof(int)); + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&optionReuseAddr, sizeof(int)); - if (bind(fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) >= 0) { - serverSocket = (ServerSocket) GLOBAL_MALLOC(sizeof(struct sServerSocket)); + if (bind(fd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) >= 0) + { + serverSocket = (ServerSocket)GLOBAL_MALLOC(sizeof(struct sServerSocket)); serverSocket->fd = fd; serverSocket->backLog = 2; - setSocketNonBlocking((Socket) serverSocket); + setSocketNonBlocking((Socket)serverSocket); } - else { + else + { close(fd); - return NULL ; + return NULL; } } @@ -271,7 +295,6 @@ ServerSocket_listen(ServerSocket self) listen(self->fd, self->backLog); } - /* CHANGED TO MAKE NON-BLOCKING --> RETURNS NULL IF NO CONNECTION IS PENDING */ Socket ServerSocket_accept(ServerSocket self) @@ -280,19 +303,22 @@ ServerSocket_accept(ServerSocket self) Socket conSocket = NULL; - fd = accept(self->fd, NULL, NULL ); + fd = accept(self->fd, NULL, NULL); - if (fd >= 0) { - conSocket = (Socket) GLOBAL_CALLOC(1, sizeof(struct sSocket)); + if (fd >= 0) + { + conSocket = (Socket)GLOBAL_CALLOC(1, sizeof(struct sSocket)); - if (conSocket) { + if (conSocket) + { conSocket->fd = fd; setSocketNonBlocking(conSocket); activateTcpNoDelay(conSocket); } - else { + else + { /* out of memory */ close(fd); @@ -313,7 +339,8 @@ ServerSocket_setBacklog(ServerSocket self, int backlog) static void closeAndShutdownSocket(int socketFd) { - if (socketFd != -1) { + if (socketFd != -1) + { if (DEBUG_SOCKET) printf("socket_linux.c: call shutdown for %i!\n", socketFd); @@ -346,10 +373,12 @@ TcpSocket_create() int sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock != -1) { - self = (Socket) GLOBAL_MALLOC(sizeof(struct sSocket)); + if (sock != -1) + { + self = (Socket)GLOBAL_MALLOC(sizeof(struct sSocket)); - if (self) { + if (self) + { self->fd = sock; self->connectTimeout = 5000; @@ -358,7 +387,8 @@ TcpSocket_create() int result = setsockopt(sock, SOL_TCP, TCP_USER_TIMEOUT, &tcpUserTimeout, sizeof(tcpUserTimeout)); #endif } - else { + else + { /* out of memory */ close(sock); @@ -366,7 +396,8 @@ TcpSocket_create() printf("SOCKET: out of memory\n"); } } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to create socket (errno=%i)\n", errno); } @@ -390,7 +421,8 @@ Socket_bind(Socket self, const char* srcAddress, int srcPort) int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress)); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to bind TCP socket (errno=%i)\n", errno); @@ -398,7 +430,7 @@ Socket_bind(Socket self, const char* srcAddress, int srcPort) self->fd = -1; return false; - } + } return true; } @@ -422,9 +454,11 @@ Socket_connectAsync(Socket self, const char* address, int port) fcntl(self->fd, F_SETFL, O_NONBLOCK); - if (connect(self->fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { + if (connect(self->fd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) + { - if (errno != EINPROGRESS) { + if (errno != EINPROGRESS) + { self->fd = -1; return false; } @@ -444,16 +478,18 @@ Socket_checkAsyncConnectState(Socket self) FD_ZERO(&fdSet); FD_SET(self->fd, &fdSet); - int selectVal = select(self->fd + 1, NULL, &fdSet , NULL, &timeout); + int selectVal = select(self->fd + 1, NULL, &fdSet, NULL, &timeout); - if (selectVal == 1) { + if (selectVal == 1) + { /* Check if connection is established */ int so_error; socklen_t len = sizeof so_error; - if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, &so_error, &len) >= 0) { + if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, &so_error, &len) >= 0) + { if (so_error == 0) return SOCKET_STATE_CONNECTED; @@ -461,10 +497,12 @@ Socket_checkAsyncConnectState(Socket self) return SOCKET_STATE_FAILED; } - else if (selectVal == 0) { + else if (selectVal == 0) + { return SOCKET_STATE_CONNECTING; } - else { + else + { return SOCKET_STATE_FAILED; } } @@ -483,21 +521,23 @@ Socket_connect(Socket self, const char* address, int port) FD_ZERO(&fdSet); FD_SET(self->fd, &fdSet); - if (select(self->fd + 1, NULL, &fdSet , NULL, &timeout) == 1) { + if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) == 1) + { /* Check if connection is established */ int so_error; socklen_t len = sizeof so_error; - if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, &so_error, &len) >= 0) { + if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, &so_error, &len) >= 0) + { if (so_error == 0) return true; } } - close (self->fd); + close(self->fd); self->fd = -1; return false; @@ -511,22 +551,24 @@ convertAddressToStr(struct sockaddr_storage* addr) bool isIPv6; - if (addr->ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) addr; + if (addr->ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)addr; port = ntohs(ipv4Addr->sin_port); inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); isIPv6 = false; } - else if (addr->ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) addr; + else if (addr->ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)addr; port = ntohs(ipv6Addr->sin6_port); inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); isIPv6 = true; } else - return NULL ; + return NULL; - char* clientConnection = (char*) GLOBAL_MALLOC(strlen(addrString) + 9); + char* clientConnection = (char*)GLOBAL_MALLOC(strlen(addrString) + 9); if (isIPv6) sprintf(clientConnection, "[%s]:%i", addrString, port); @@ -542,7 +584,8 @@ Socket_getPeerAddress(Socket self) struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); - if (getpeername(self->fd, (struct sockaddr*) &addr, &addrLen) == 0) { + if (getpeername(self->fd, (struct sockaddr*)&addr, &addrLen) == 0) + { return convertAddressToStr(&addr); } else @@ -555,7 +598,8 @@ Socket_getLocalAddress(Socket self) struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); - if (getsockname(self->fd, (struct sockaddr*) &addr, &addrLen) == 0) { + if (getsockname(self->fd, (struct sockaddr*)&addr, &addrLen) == 0) + { return convertAddressToStr(&addr); } else @@ -568,27 +612,29 @@ Socket_getPeerAddressStatic(Socket self, char* peerAddressString) struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); - getpeername(self->fd, (struct sockaddr*) &addr, &addrLen); + getpeername(self->fd, (struct sockaddr*)&addr, &addrLen); char addrString[INET6_ADDRSTRLEN + 7]; int port; bool isIPv6; - if (addr.ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &addr; + if (addr.ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)&addr; port = ntohs(ipv4Addr->sin_port); inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); isIPv6 = false; } - else if (addr.ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &addr; + else if (addr.ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)&addr; port = ntohs(ipv6Addr->sin6_port); inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); isIPv6 = true; } else - return NULL ; + return NULL; if (isIPv6) sprintf(peerAddressString, "[%s]:%i", addrString, port); @@ -609,18 +655,20 @@ Socket_read(Socket self, uint8_t* buf, int size) if (read_bytes == 0) return -1; - if (read_bytes == -1) { + if (read_bytes == -1) + { int error = errno; - switch (error) { + switch (error) + { - case EAGAIN: - return 0; - case EBADF: - return -1; + case EAGAIN: + return 0; + case EBADF: + return -1; - default: - return -1; + default: + return -1; } } @@ -663,21 +711,25 @@ UdpSocket_createUsingNamespace(int namespace) int sock = socket(namespace, SOCK_DGRAM, IPPROTO_UDP); - if (sock != -1) { - self = (UdpSocket) GLOBAL_MALLOC(sizeof(struct sSocket)); + if (sock != -1) + { + self = (UdpSocket)GLOBAL_MALLOC(sizeof(struct sSocket)); - if (self) { + if (self) + { self->fd = sock; self->namespace = namespace; } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to allocate memory\n"); close(sock); } } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to create UDP socket (errno=%i)\n", errno); } @@ -700,36 +752,42 @@ UdpSocket_createIpV6() bool UdpSocket_addGroupMembership(UdpSocket self, const char* multicastAddress) { - if (self->namespace == AF_INET) { + if (self->namespace == AF_INET) + { struct ip_mreq mreq; - if (!inet_aton(multicastAddress, &(mreq.imr_multiaddr))) { + if (!inet_aton(multicastAddress, &(mreq.imr_multiaddr))) + { printf("SOCKET: Invalid IPv4 multicast address\n"); return false; } - else { + else + { mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if (setsockopt(self->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { + if (setsockopt(self->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) + { printf("SOCKET: failed to set IPv4 multicast group (errno: %i)\n", errno); return false; } - } return true; } - else if (self->namespace == AF_INET6) { + else if (self->namespace == AF_INET6) + { struct ipv6_mreq mreq; - if (inet_pton(AF_INET6, multicastAddress, &(mreq.ipv6mr_multiaddr)) < 1) { + if (inet_pton(AF_INET6, multicastAddress, &(mreq.ipv6mr_multiaddr)) < 1) + { printf("SOCKET: failed to set IPv6 multicast group (errno: %i)\n", errno); return false; } mreq.ipv6mr_interface = 0; - if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { + if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) + { printf("SOCKET: failed to set IPv6 multicast group (errno: %i)\n", errno); return false; } @@ -743,16 +801,20 @@ UdpSocket_addGroupMembership(UdpSocket self, const char* multicastAddress) bool UdpSocket_setMulticastTtl(UdpSocket self, int ttl) { - if (self->namespace == AF_INET) { - if (setsockopt(self->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == -1) { + if (self->namespace == AF_INET) + { + if (setsockopt(self->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == -1) + { printf("SOCKET: failed to set IPv4 multicast TTL (errno: %i)\n", errno); return false; } return true; } - else if (self->namespace == AF_INET6) { - if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) == -1) { + else if (self->namespace == AF_INET6) + { + if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) == -1) + { printf("SOCKET: failed to set IPv6 multicast TTL(hops) (errno: %i)\n", errno); return false; } @@ -766,10 +828,11 @@ UdpSocket_setMulticastTtl(UdpSocket self, int ttl) bool UdpSocket_bind(UdpSocket self, const char* address, int port) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_in localAddress; - if (!prepareAddress(address, port, &localAddress)) { + if (!prepareAddress(address, port, &localAddress)) + { close(self->fd); self->fd = 0; return false; @@ -777,7 +840,8 @@ UdpSocket_bind(UdpSocket self, const char* address, int port) int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress)); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to bind UDP socket (errno=%i)\n", errno); @@ -793,10 +857,11 @@ UdpSocket_bind(UdpSocket self, const char* address, int port) bool UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, int msgSize) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_in remoteAddress; - if (!prepareAddress(address, port, &remoteAddress)) { + if (!prepareAddress(address, port, &remoteAddress)) + { if (DEBUG_SOCKET) printf("SOCKET: failed to lookup remote address %s\n", address); @@ -806,14 +871,17 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in int result = sendto(self->fd, msg, msgSize, 0, (struct sockaddr*)&remoteAddress, sizeof(remoteAddress)); - if (result == msgSize) { + if (result == msgSize) + { return true; } - else if (result == -1) { + else if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to send UDP message (errno=%i)\n", errno); } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to send UDP message (insufficient data sent)\n"); } @@ -824,31 +892,35 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in int UdpSocket_receiveFrom(UdpSocket self, char* address, int maxAddrSize, uint8_t* msg, int msgSize) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_storage remoteAddress; socklen_t structSize = sizeof(struct sockaddr_storage); int result = recvfrom(self->fd, msg, msgSize, MSG_DONTWAIT, (struct sockaddr*)&remoteAddress, &structSize); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to receive UDP message (errno=%i)\n", errno); } - if (address) { + if (address) + { bool isIPv6; char addrString[INET6_ADDRSTRLEN + 7]; int port; - if (remoteAddress.ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &remoteAddress; + if (remoteAddress.ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)&remoteAddress; port = ntohs(ipv4Addr->sin_port); inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); isIPv6 = false; } - else if (remoteAddress.ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &remoteAddress; + else if (remoteAddress.ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)&remoteAddress; port = ntohs(ipv6Addr->sin6_port); inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); isIPv6 = true; @@ -862,19 +934,22 @@ UdpSocket_receiveFrom(UdpSocket self, char* address, int maxAddrSize, uint8_t* m snprintf(address, maxAddrSize, "%s:%i", addrString, port); } - if (address) { + if (address) + { bool isIPv6; char addrString[INET6_ADDRSTRLEN + 7]; int port; - if (remoteAddress.ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &remoteAddress; + if (remoteAddress.ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)&remoteAddress; port = ntohs(ipv4Addr->sin_port); inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); isIPv6 = false; } - else if (remoteAddress.ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &remoteAddress; + else if (remoteAddress.ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)&remoteAddress; port = ntohs(ipv6Addr->sin6_port); inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); isIPv6 = true; diff --git a/hal/socket/linux/socket_linux.c b/hal/socket/linux/socket_linux.c index dc168c94..ce435cd8 100644 --- a/hal/socket/linux/socket_linux.c +++ b/hal/socket/linux/socket_linux.c @@ -8,49 +8,52 @@ */ #include "hal_socket.h" -#include -#include -#include #include -#include -#include -#include -#include #include -#include #include -#include /* required for TCP keepalive */ #include +#include +#include +#include /* required for TCP keepalive */ +#include +#include +#include +#include +#include +#include #define _GNU_SOURCE -#include #include +#include - -#include "linked_list.h" #include "hal_thread.h" #include "lib_memory.h" +#include "linked_list.h" #ifndef DEBUG_SOCKET #define DEBUG_SOCKET 0 #endif -struct sSocket { +struct sSocket +{ int fd; uint32_t connectTimeout; }; -struct sServerSocket { +struct sServerSocket +{ int fd; int backLog; }; -struct sUdpSocket { +struct sUdpSocket +{ int fd; int namespace; /* IPv4: AF_INET; IPv6: AF_INET6 */ }; -struct sHandleSet { +struct sHandleSet +{ LinkedList sockets; bool pollfdIsUpdated; struct pollfd* fds; @@ -60,23 +63,26 @@ struct sHandleSet { HandleSet Handleset_new(void) { - HandleSet self = (HandleSet) GLOBAL_MALLOC(sizeof(struct sHandleSet)); + HandleSet self = (HandleSet)GLOBAL_MALLOC(sizeof(struct sHandleSet)); - if (self) { - self->sockets = LinkedList_create(); - self->pollfdIsUpdated = false; - self->fds = NULL; - self->nfds = 0; - } + if (self) + { + self->sockets = LinkedList_create(); + self->pollfdIsUpdated = false; + self->fds = NULL; + self->nfds = 0; + } - return self; + return self; } void Handleset_reset(HandleSet self) { - if (self) { - if (self->sockets) { + if (self) + { + if (self->sockets) + { LinkedList_destroyStatic(self->sockets); self->sockets = LinkedList_create(); self->pollfdIsUpdated = false; @@ -87,17 +93,19 @@ Handleset_reset(HandleSet self) void Handleset_addSocket(HandleSet self, const Socket sock) { - if (self != NULL && sock != NULL && sock->fd != -1) { + if (self != NULL && sock != NULL && sock->fd != -1) + { - LinkedList_add(self->sockets, sock); - self->pollfdIsUpdated = false; - } + LinkedList_add(self->sockets, sock); + self->pollfdIsUpdated = false; + } } void Handleset_removeSocket(HandleSet self, const Socket sock) { - if (self && self->sockets && sock) { + if (self && self->sockets && sock) + { LinkedList_remove(self->sockets, sock); self->pollfdIsUpdated = false; } @@ -107,8 +115,10 @@ int Handleset_waitReady(HandleSet self, unsigned int timeoutMs) { /* check if pollfd array is updated */ - if (self->pollfdIsUpdated == false) { - if (self->fds) { + if (self->pollfdIsUpdated == false) + { + if (self->fds) + { GLOBAL_FREEMEM(self->fds); self->fds = NULL; } @@ -119,13 +129,16 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) int i; - for (i = 0; i < self->nfds; i++) { + for (i = 0; i < self->nfds; i++) + { LinkedList sockElem = LinkedList_get(self->sockets, i); - if (sockElem) { - Socket sock = (Socket) LinkedList_getData(sockElem); + if (sockElem) + { + Socket sock = (Socket)LinkedList_getData(sockElem); - if (sock) { + if (sock) + { self->fds[i].fd = sock->fd; self->fds[i].events = POLL_IN; } @@ -135,21 +148,25 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) self->pollfdIsUpdated = true; } - if (self->fds && self->nfds > 0) { + if (self->fds && self->nfds > 0) + { int result = poll(self->fds, self->nfds, timeoutMs); - if (result == -1 && errno == EINTR) { + if (result == -1 && errno == EINTR) + { result = 0; } - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: poll error (errno: %i)\n", errno); } return result; } - else { + else + { /* there is no socket to wait for */ return 0; } @@ -158,7 +175,8 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) void Handleset_destroy(HandleSet self) { - if (self) { + if (self) + { if (self->sockets) LinkedList_destroyStatic(self->sockets); @@ -178,26 +196,30 @@ Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count) optval = 1; - if (setsockopt(self->fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen)) { + if (setsockopt(self->fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen)) + { if (DEBUG_SOCKET) printf("SOCKET: Failed to enable TCP keepalive\n"); } #if defined TCP_KEEPCNT optval = idleTime; - if (setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen)) { + if (setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen)) + { if (DEBUG_SOCKET) printf("SOCKET: Failed to set TCP keepalive TCP_KEEPIDLE parameter\n"); } optval = interval; - if (setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen)) { + if (setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen)) + { if (DEBUG_SOCKET) printf("SOCKET: Failed to set TCP keepalive TCP_KEEPINTVL parameter\n"); } optval = count; - if (setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen)) { + if (setsockopt(self->fd, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen)) + { if (DEBUG_SOCKET) printf("SOCKET: Failed to set TCP keepalive TCP_KEEPCNT parameter\n"); } @@ -211,18 +233,20 @@ prepareAddress(const char* address, int port, struct sockaddr_in* sockaddr) { bool retVal = true; - memset((char *) sockaddr, 0, sizeof(struct sockaddr_in)); + memset((char*)sockaddr, 0, sizeof(struct sockaddr_in)); - if (address != NULL) { + if (address != NULL) + { struct addrinfo addressHints; - struct addrinfo *lookupResult; + struct addrinfo* lookupResult; int result; memset(&addressHints, 0, sizeof(struct addrinfo)); addressHints.ai_family = AF_INET; result = getaddrinfo(address, NULL, &addressHints, &lookupResult); - if (result != 0) { + if (result != 0) + { if (DEBUG_SOCKET) printf("SOCKET: getaddrinfo failed (code=%i)\n", result); @@ -260,7 +284,7 @@ activateTcpNoDelay(Socket self) { /* activate TCP_NODELAY option - packets will be sent immediately */ int flag = 1; - setsockopt(self->fd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int)); + setsockopt(self->fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int)); } ServerSocket @@ -270,22 +294,25 @@ TcpServerSocket_create(const char* address, int port) int fd; - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) { + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) >= 0) + { struct sockaddr_in serverAddress; - if (!prepareAddress(address, port, &serverAddress)) { + if (!prepareAddress(address, port, &serverAddress)) + { close(fd); return NULL; } int optionReuseAddr = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &optionReuseAddr, sizeof(int)); + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&optionReuseAddr, sizeof(int)); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) int tcpUserTimeout = 10000; - int result = setsockopt(fd, SOL_TCP, TCP_USER_TIMEOUT, &tcpUserTimeout, sizeof(tcpUserTimeout)); + int result = setsockopt(fd, SOL_TCP, TCP_USER_TIMEOUT, &tcpUserTimeout, sizeof(tcpUserTimeout)); - if (result < 0) { + if (result < 0) + { if (DEBUG_SOCKET) printf("SOCKET: failed to set TCP_USER_TIMEOUT\n"); } @@ -293,16 +320,18 @@ TcpServerSocket_create(const char* address, int port) #warning "TCP_USER_TIMEOUT not supported by linux kernel" #endif - if (bind(fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) >= 0) { - serverSocket = (ServerSocket) GLOBAL_MALLOC(sizeof(struct sServerSocket)); + if (bind(fd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) >= 0) + { + serverSocket = (ServerSocket)GLOBAL_MALLOC(sizeof(struct sServerSocket)); serverSocket->fd = fd; serverSocket->backLog = 2; - setSocketNonBlocking((Socket) serverSocket); + setSocketNonBlocking((Socket)serverSocket); } - else { + else + { close(fd); - return NULL ; + return NULL; } } @@ -312,7 +341,8 @@ TcpServerSocket_create(const char* address, int port) void ServerSocket_listen(ServerSocket self) { - if (listen(self->fd, self->backLog) == -1) { + if (listen(self->fd, self->backLog) == -1) + { if (DEBUG_SOCKET) printf("SOCKET: listen failed (errno: %i)\n", errno); } @@ -326,19 +356,22 @@ ServerSocket_accept(ServerSocket self) Socket conSocket = NULL; - fd = accept(self->fd, NULL, NULL ); + fd = accept(self->fd, NULL, NULL); - if (fd >= 0) { - conSocket = (Socket) GLOBAL_CALLOC(1, sizeof(struct sSocket)); + if (fd >= 0) + { + conSocket = (Socket)GLOBAL_CALLOC(1, sizeof(struct sSocket)); - if (conSocket) { + if (conSocket) + { conSocket->fd = fd; setSocketNonBlocking(conSocket); activateTcpNoDelay(conSocket); } - else { + else + { /* out of memory */ close(fd); @@ -346,7 +379,8 @@ ServerSocket_accept(ServerSocket self) printf("SOCKET: out of memory\n"); } } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: accept failed (errno=%i)\n", errno); } @@ -363,7 +397,8 @@ ServerSocket_setBacklog(ServerSocket self, int backlog) static void closeAndShutdownSocket(int socketFd) { - if (socketFd != -1) { + if (socketFd != -1) + { if (DEBUG_SOCKET) printf("SOCKET: call shutdown for %i!\n", socketFd); @@ -371,14 +406,16 @@ closeAndShutdownSocket(int socketFd) /* shutdown is required to unblock read or accept in another thread! */ int result = shutdown(socketFd, SHUT_RDWR); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: shutdown error: %i\n", errno); } result = close(socketFd); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: close error: %i\n", errno); } @@ -406,24 +443,28 @@ TcpSocket_create() int sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock != -1) { - self = (Socket) GLOBAL_MALLOC(sizeof(struct sSocket)); + if (sock != -1) + { + self = (Socket)GLOBAL_MALLOC(sizeof(struct sSocket)); - if (self) { + if (self) + { self->fd = sock; self->connectTimeout = 5000; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37) int tcpUserTimeout = 10000; - int result = setsockopt(sock, SOL_TCP, TCP_USER_TIMEOUT, &tcpUserTimeout, sizeof(tcpUserTimeout)); + int result = setsockopt(sock, SOL_TCP, TCP_USER_TIMEOUT, &tcpUserTimeout, sizeof(tcpUserTimeout)); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to set TCP_USER_TIMEOUT (errno=%i)\n", errno); } #endif } - else { + else + { /* out of memory */ close(sock); @@ -431,7 +472,8 @@ TcpSocket_create() printf("SOCKET: out of memory\n"); } } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to create socket (errno=%i)\n", errno); } @@ -455,7 +497,8 @@ Socket_bind(Socket self, const char* srcAddress, int srcPort) int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress)); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to bind TCP socket (errno=%i)\n", errno); @@ -463,7 +506,7 @@ Socket_bind(Socket self, const char* srcAddress, int srcPort) self->fd = -1; return false; - } + } return true; } @@ -483,10 +526,13 @@ Socket_connectAsync(Socket self, const char* address, int port) fcntl(self->fd, F_SETFL, O_NONBLOCK); - if (connect(self->fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { + if (connect(self->fd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) < 0) + { - if (errno != EINPROGRESS) { - if (close(self->fd) == -1) { + if (errno != EINPROGRESS) + { + if (close(self->fd) == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to close socket (errno: %i)\n", errno); } @@ -509,14 +555,16 @@ Socket_checkAsyncConnectState(Socket self) int result = poll(fds, 1, 0); - if (result == 1) { + if (result == 1) + { /* Check if connection is established */ int so_error; socklen_t len = sizeof so_error; - if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, &so_error, &len) >= 0) { + if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, &so_error, &len) >= 0) + { if (so_error == 0) return SOCKET_STATE_CONNECTED; @@ -524,10 +572,12 @@ Socket_checkAsyncConnectState(Socket self) return SOCKET_STATE_FAILED; } - else if (result == 0) { + else if (result == 0) + { return SOCKET_STATE_CONNECTING; } - else { + else + { return SOCKET_STATE_FAILED; } } @@ -545,21 +595,23 @@ Socket_connect(Socket self, const char* address, int port) int result = poll(fds, 1, self->connectTimeout); - if (result == 1) { + if (result == 1) + { /* Check if connection is established */ int so_error; socklen_t len = sizeof so_error; - if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, &so_error, &len) >= 0) { + if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, &so_error, &len) >= 0) + { if (so_error == 0) return true; } } - close (self->fd); + close(self->fd); self->fd = -1; return false; @@ -573,22 +625,24 @@ convertAddressToStr(struct sockaddr_storage* addr) bool isIPv6; - if (addr->ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) addr; + if (addr->ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)addr; port = ntohs(ipv4Addr->sin_port); inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); isIPv6 = false; } - else if (addr->ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) addr; + else if (addr->ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)addr; port = ntohs(ipv6Addr->sin6_port); inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); isIPv6 = true; } else - return NULL ; + return NULL; - char* clientConnection = (char*) GLOBAL_MALLOC(strlen(addrString) + 9); + char* clientConnection = (char*)GLOBAL_MALLOC(strlen(addrString) + 9); if (isIPv6) sprintf(clientConnection, "[%s]:%i", addrString, port); @@ -604,7 +658,8 @@ Socket_getPeerAddress(Socket self) struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); - if (getpeername(self->fd, (struct sockaddr*) &addr, &addrLen) == 0) { + if (getpeername(self->fd, (struct sockaddr*)&addr, &addrLen) == 0) + { return convertAddressToStr(&addr); } else @@ -617,7 +672,8 @@ Socket_getLocalAddress(Socket self) struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); - if (getsockname(self->fd, (struct sockaddr*) &addr, &addrLen) == 0) { + if (getsockname(self->fd, (struct sockaddr*)&addr, &addrLen) == 0) + { return convertAddressToStr(&addr); } else @@ -629,28 +685,37 @@ Socket_getPeerAddressStatic(Socket self, char* peerAddressString) { struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); + memset(&addr, 0, sizeof(addr)); - getpeername(self->fd, (struct sockaddr*) &addr, &addrLen); + if (getpeername(self->fd, (struct sockaddr*)&addr, &addrLen) == -1) + { + if (DEBUG_SOCKET) + printf("DEBUG_SOCKET: getpeername -> errno: %i\n", errno); + + return NULL; + } char addrString[INET6_ADDRSTRLEN + 7]; int port; bool isIPv6; - if (addr.ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &addr; + if (addr.ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)&addr; port = ntohs(ipv4Addr->sin_port); inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); isIPv6 = false; } - else if (addr.ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &addr; + else if (addr.ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)&addr; port = ntohs(ipv6Addr->sin6_port); inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); isIPv6 = true; } else - return NULL ; + return NULL; if (isIPv6) sprintf(peerAddressString, "[%s]:%i", addrString, port); @@ -671,22 +736,24 @@ Socket_read(Socket self, uint8_t* buf, int size) if (read_bytes == 0) return -1; - if (read_bytes == -1) { + if (read_bytes == -1) + { int error = errno; - switch (error) { + switch (error) + { - case EAGAIN: - return 0; - case EBADF: - return -1; + case EAGAIN: + return 0; + case EBADF: + return -1; - default: + default: - if (DEBUG_SOCKET) - printf("DEBUG_SOCKET: recv returned error (errno=%i)\n", error); + if (DEBUG_SOCKET) + printf("DEBUG_SOCKET: recv returned error (errno=%i)\n", error); - return -1; + return -1; } } @@ -702,11 +769,14 @@ Socket_write(Socket self, uint8_t* buf, int size) /* MSG_NOSIGNAL - prevent send to signal SIGPIPE when peer unexpectedly closed the socket */ int retVal = send(self->fd, buf, size, MSG_NOSIGNAL | MSG_DONTWAIT); - if (retVal == -1) { - if (errno == EAGAIN) { + if (retVal == -1) + { + if (errno == EAGAIN) + { return 0; } - else { + else + { if (DEBUG_SOCKET) printf("DEBUG_SOCKET: send returned error (errno=%i)\n", errno); } @@ -736,21 +806,25 @@ UdpSocket_createUsingNamespace(int namespace) int sock = socket(namespace, SOCK_DGRAM, IPPROTO_UDP); - if (sock != -1) { - self = (UdpSocket) GLOBAL_MALLOC(sizeof(struct sSocket)); + if (sock != -1) + { + self = (UdpSocket)GLOBAL_MALLOC(sizeof(struct sSocket)); - if (self) { + if (self) + { self->fd = sock; self->namespace = namespace; } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to allocate memory\n"); close(sock); } } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to create UDP socket (errno=%i)\n", errno); } @@ -773,36 +847,42 @@ UdpSocket_createIpV6() bool UdpSocket_addGroupMembership(UdpSocket self, const char* multicastAddress) { - if (self->namespace == AF_INET) { + if (self->namespace == AF_INET) + { struct ip_mreq mreq; - if (!inet_aton(multicastAddress, &(mreq.imr_multiaddr))) { + if (!inet_aton(multicastAddress, &(mreq.imr_multiaddr))) + { printf("SOCKET: Invalid IPv4 multicast address\n"); return false; } - else { + else + { mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if (setsockopt(self->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { + if (setsockopt(self->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) + { printf("SOCKET: failed to set IPv4 multicast group (errno: %i)\n", errno); return false; } - } return true; } - else if (self->namespace == AF_INET6) { + else if (self->namespace == AF_INET6) + { struct ipv6_mreq mreq; - if (inet_pton(AF_INET6, multicastAddress, &(mreq.ipv6mr_multiaddr)) < 1) { + if (inet_pton(AF_INET6, multicastAddress, &(mreq.ipv6mr_multiaddr)) < 1) + { printf("SOCKET: failed to set IPv6 multicast group (errno: %i)\n", errno); return false; } mreq.ipv6mr_interface = 0; - if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { + if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) + { printf("SOCKET: failed to set IPv6 multicast group (errno: %i)\n", errno); return false; } @@ -816,16 +896,20 @@ UdpSocket_addGroupMembership(UdpSocket self, const char* multicastAddress) bool UdpSocket_setMulticastTtl(UdpSocket self, int ttl) { - if (self->namespace == AF_INET) { - if (setsockopt(self->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == -1) { + if (self->namespace == AF_INET) + { + if (setsockopt(self->fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) == -1) + { printf("SOCKET: failed to set IPv4 multicast TTL (errno: %i)\n", errno); return false; } return true; } - else if (self->namespace == AF_INET6) { - if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) == -1) { + else if (self->namespace == AF_INET6) + { + if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &ttl, sizeof(ttl)) == -1) + { printf("SOCKET: failed to set IPv6 multicast TTL(hops) (errno: %i)\n", errno); return false; } @@ -839,10 +923,11 @@ UdpSocket_setMulticastTtl(UdpSocket self, int ttl) bool UdpSocket_bind(UdpSocket self, const char* address, int port) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_in localAddress; - if (!prepareAddress(address, port, &localAddress)) { + if (!prepareAddress(address, port, &localAddress)) + { close(self->fd); self->fd = 0; return false; @@ -850,7 +935,8 @@ UdpSocket_bind(UdpSocket self, const char* address, int port) int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress)); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to bind UDP socket (errno=%i)\n", errno); @@ -866,10 +952,11 @@ UdpSocket_bind(UdpSocket self, const char* address, int port) bool UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, int msgSize) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_in remoteAddress; - if (!prepareAddress(address, port, &remoteAddress)) { + if (!prepareAddress(address, port, &remoteAddress)) + { if (DEBUG_SOCKET) printf("SOCKET: failed to lookup remote address %s\n", address); @@ -879,14 +966,17 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in int result = sendto(self->fd, msg, msgSize, 0, (struct sockaddr*)&remoteAddress, sizeof(remoteAddress)); - if (result == msgSize) { + if (result == msgSize) + { return true; } - else if (result == -1) { + else if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to send UDP message (errno=%i)\n", errno); } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to send UDP message (insufficient data sent)\n"); } @@ -897,31 +987,35 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in int UdpSocket_receiveFrom(UdpSocket self, char* address, int maxAddrSize, uint8_t* msg, int msgSize) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_storage remoteAddress; memset(&remoteAddress, 0, sizeof(struct sockaddr_storage)); socklen_t structSize = sizeof(struct sockaddr_storage); int result = recvfrom(self->fd, msg, msgSize, MSG_DONTWAIT, (struct sockaddr*)&remoteAddress, &structSize); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to receive UDP message (errno=%i)\n", errno); } - if (address) { + if (address) + { bool isIPv6; char addrString[INET6_ADDRSTRLEN + 7]; int port; - if (remoteAddress.ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &remoteAddress; + if (remoteAddress.ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)&remoteAddress; port = ntohs(ipv4Addr->sin_port); inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); isIPv6 = false; } - else if (remoteAddress.ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &remoteAddress; + else if (remoteAddress.ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)&remoteAddress; port = ntohs(ipv6Addr->sin6_port); inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); isIPv6 = true; diff --git a/hal/socket/win32/socket_win32.c b/hal/socket/win32/socket_win32.c index 8976a825..6f6b6c78 100644 --- a/hal/socket/win32/socket_win32.c +++ b/hal/socket/win32/socket_win32.c @@ -1,7 +1,7 @@ /* * socket_win32.c * - * Copyright 2013-2021 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of Platform Abstraction Layer (libpal) * for libiec61850, libmms, and lib60870. @@ -9,56 +9,64 @@ #define _WINSOCK_DEPRECATED_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS + #include #include #include #include #include -#pragma comment (lib, "Ws2_32.lib") +#pragma comment(lib, "Ws2_32.lib") -#include "lib_memory.h" #include "hal_socket.h" -#include "stack_config.h" +#include "lib_memory.h" -#define DEBUG_SOCKET 1 +#ifndef DEBUG_SOCKET +#define DEBUG_SOCKET 0 +#endif #ifndef __MINGW64_VERSION_MAJOR -struct tcp_keepalive { - u_long onoff; - u_long keepalivetime; - u_long keepaliveinterval; +struct tcp_keepalive +{ + u_long onoff; + u_long keepalivetime; + u_long keepaliveinterval; }; #endif -#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4) +#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR, 4) -struct sSocket { +struct sSocket +{ SOCKET fd; uint32_t connectTimeout; }; -struct sServerSocket { +struct sServerSocket +{ SOCKET fd; int backLog; }; -struct sHandleSet { +struct sHandleSet +{ fd_set handles; SOCKET maxHandle; }; -struct sUdpSocket { +struct sUdpSocket +{ SOCKET fd; - int ns; /* IPv4: AF_INET; IPv6: AF_INET6 */ + int ns; /* IPv4: AF_INET; IPv6: AF_INET6 */ }; HandleSet Handleset_new(void) { - HandleSet result = (HandleSet) GLOBAL_MALLOC(sizeof(struct sHandleSet)); + HandleSet result = (HandleSet)GLOBAL_MALLOC(sizeof(struct sHandleSet)); - if (result != NULL) { + if (result != NULL) + { FD_ZERO(&result->handles); result->maxHandle = INVALID_SOCKET; } @@ -76,19 +84,21 @@ Handleset_reset(HandleSet self) void Handleset_addSocket(HandleSet self, const Socket sock) { - if (self != NULL && sock != NULL && sock->fd != INVALID_SOCKET) { + if (self != NULL && sock != NULL && sock->fd != INVALID_SOCKET) + { - FD_SET(sock->fd, &self->handles); + FD_SET(sock->fd, &self->handles); - if ((sock->fd > self->maxHandle) || (self->maxHandle == INVALID_SOCKET)) - self->maxHandle = sock->fd; - } + if ((sock->fd > self->maxHandle) || (self->maxHandle == INVALID_SOCKET)) + self->maxHandle = sock->fd; + } } void Handleset_removeSocket(HandleSet self, const Socket sock) { - if (self != NULL && sock != NULL && sock->fd != INVALID_SOCKET) { + if (self != NULL && sock != NULL && sock->fd != INVALID_SOCKET) + { FD_CLR(sock->fd, &self->handles); } } @@ -98,7 +108,8 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) { int result; - if ((self != NULL) && (self->maxHandle != INVALID_SOCKET)) { + if ((self != NULL) && (self->maxHandle != INVALID_SOCKET)) + { struct timeval timeout; timeout.tv_sec = timeoutMs / 1000; @@ -109,7 +120,9 @@ Handleset_waitReady(HandleSet self, unsigned int timeoutMs) memcpy((void*)&handles, &(self->handles), sizeof(fd_set)); result = select(self->maxHandle + 1, &handles, NULL, NULL, &timeout); - } else { + } + else + { result = -1; } @@ -131,27 +144,26 @@ Socket_activateTcpKeepAlive(Socket self, int idleTime, int interval, int count) (void)count; /* not supported in windows socket API */ struct tcp_keepalive keepalive; - DWORD retVal=0; + DWORD retVal = 0; keepalive.onoff = 1; keepalive.keepalivetime = idleTime * 1000; keepalive.keepaliveinterval = interval * 1000; - if (WSAIoctl(self->fd, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), - NULL, 0, &retVal, NULL, NULL) == SOCKET_ERROR) - { - if (DEBUG_SOCKET) - printf("WIN32_SOCKET: WSAIotcl(SIO_KEEPALIVE_VALS) failed: %d\n", - WSAGetLastError()); - } + if (WSAIoctl(self->fd, SIO_KEEPALIVE_VALS, &keepalive, sizeof(keepalive), NULL, 0, &retVal, NULL, NULL) == + SOCKET_ERROR) + { + if (DEBUG_SOCKET) + printf("WIN32_SOCKET: WSAIotcl(SIO_KEEPALIVE_VALS) failed: %d\n", WSAGetLastError()); + } } - static void setSocketNonBlocking(Socket self) { unsigned long mode = 1; - if (ioctlsocket(self->fd, FIONBIO, &mode) != 0) { + if (ioctlsocket(self->fd, FIONBIO, &mode) != 0) + { if (DEBUG_SOCKET) printf("WIN32_SOCKET: failed to set socket non-blocking!\n"); } @@ -164,18 +176,19 @@ setSocketNonBlocking(Socket self) } static bool -prepareAddress(const char *address, int port, struct sockaddr_in *sockaddr) +prepareAddress(const char* address, int port, struct sockaddr_in* sockaddr) { - memset((char *)sockaddr, 0, sizeof(struct sockaddr_in)); + memset((char*)sockaddr, 0, sizeof(struct sockaddr_in)); - if (address != NULL) { - struct hostent *server; + if (address != NULL) + { + struct hostent* server; server = gethostbyname(address); if (server == NULL) return false; - memcpy((char *)&sockaddr->sin_addr.s_addr, (char *)server->h_addr, server->h_length); + memcpy((char*)&sockaddr->sin_addr.s_addr, (char*)server->h_addr, server->h_length); } else sockaddr->sin_addr.s_addr = htonl(INADDR_ANY); @@ -189,20 +202,22 @@ prepareAddress(const char *address, int port, struct sockaddr_in *sockaddr) static bool wsaStartUp(void) { - if (wsaStartupCalled == false) { + if (wsaStartupCalled == false) + { int ec; WSADATA wsa; - if ((ec = WSAStartup(MAKEWORD(2, 0), &wsa)) != 0) { + if ((ec = WSAStartup(MAKEWORD(2, 0), &wsa)) != 0) + { if (DEBUG_SOCKET) printf("WIN32_SOCKET: winsock error: code %i\n", ec); return false; } - else { + else + { wsaStartupCalled = true; return true; } - } else return true; @@ -211,12 +226,13 @@ wsaStartUp(void) static void wsaShutdown(void) { - if (wsaStartupCalled) { - if (socketCount == 0) { + if (wsaStartupCalled) + { + if (socketCount == 0) + { WSACleanup(); wsaStartupCalled = false; } - } } @@ -237,7 +253,8 @@ TcpServerSocket_create(const char* address, int port) listen_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (listen_socket == INVALID_SOCKET) { + if (listen_socket == INVALID_SOCKET) + { if (DEBUG_SOCKET) printf("WIN32_SOCKET: socket failed with error: %i\n", WSAGetLastError()); @@ -247,11 +264,12 @@ TcpServerSocket_create(const char* address, int port) } int optionReuseAddr = 1; - setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&optionReuseAddr, sizeof(int)); + setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&optionReuseAddr, sizeof(int)); ec = bind(listen_socket, (struct sockaddr*)&server_addr, sizeof(server_addr)); - if (ec == SOCKET_ERROR) { + if (ec == SOCKET_ERROR) + { if (DEBUG_SOCKET) printf("WIN32_SOCKET: bind failed with error:%i\n", WSAGetLastError()); closesocket(listen_socket); @@ -263,7 +281,8 @@ TcpServerSocket_create(const char* address, int port) serverSocket = (ServerSocket)GLOBAL_MALLOC(sizeof(struct sServerSocket)); - if (serverSocket) { + if (serverSocket) + { serverSocket->fd = listen_socket; serverSocket->backLog = 10; @@ -271,7 +290,8 @@ TcpServerSocket_create(const char* address, int port) socketCount++; } - else { + else + { closesocket(listen_socket); wsaShutdown(); } @@ -292,8 +312,9 @@ ServerSocket_accept(ServerSocket self) SOCKET fd = accept(self->fd, NULL, NULL); - if (fd != INVALID_SOCKET) { - conSocket = (Socket) GLOBAL_CALLOC(1, sizeof(struct sSocket)); + if (fd != INVALID_SOCKET) + { + conSocket = (Socket)GLOBAL_CALLOC(1, sizeof(struct sSocket)); conSocket->fd = fd; socketCount++; @@ -303,7 +324,8 @@ ServerSocket_accept(ServerSocket self) if (DEBUG_SOCKET) printf("WIN32_SOCKET: connection accepted\n"); } - else { + else + { if (DEBUG_SOCKET) printf("WIN32_SOCKET: accept failed\n"); } @@ -320,7 +342,8 @@ ServerSocket_setBacklog(ServerSocket self, int backlog) void ServerSocket_destroy(ServerSocket self) { - if (self->fd != INVALID_SOCKET) { + if (self->fd != INVALID_SOCKET) + { shutdown(self->fd, 2); closesocket(self->fd); socketCount--; @@ -341,25 +364,28 @@ TcpSocket_create() SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock != INVALID_SOCKET) { - self = (Socket) GLOBAL_MALLOC(sizeof(struct sSocket)); + if (sock != INVALID_SOCKET) + { + self = (Socket)GLOBAL_MALLOC(sizeof(struct sSocket)); - if (self) { + if (self) + { self->fd = sock; self->connectTimeout = 5000; socketCount++; } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to create socket - cannot allocate memory\n"); closesocket(sock); wsaShutdown(); } - } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to create socket (error code=%i)\n", WSAGetLastError()); } @@ -383,7 +409,8 @@ Socket_bind(Socket self, const char* srcAddress, int srcPort) int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress)); - if (result == SOCKET_ERROR) { + if (result == SOCKET_ERROR) + { if (DEBUG_SOCKET) printf("SOCKET: failed to bind TCP socket (errno=%i)\n", WSAGetLastError()); @@ -403,22 +430,19 @@ Socket_connectAsync(Socket self, const char* address, int port) printf("WIN32_SOCKET: Socket_connect: %s:%i\n", address, port); struct sockaddr_in serverAddress; - WSADATA wsa; - int ec; - if ((ec = WSAStartup(MAKEWORD(2,0), &wsa)) != 0) { - if (DEBUG_SOCKET) - printf("WIN32_SOCKET: winsock error: code %i\n", ec); + if (wsaStartUp() == false) return false; - } if (!prepareAddress(address, port, &serverAddress)) return false; setSocketNonBlocking(self); - if (connect(self->fd, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) == SOCKET_ERROR) { - if (WSAGetLastError() != WSAEWOULDBLOCK) { + if (connect(self->fd, (struct sockaddr*)&serverAddress, sizeof(serverAddress)) == SOCKET_ERROR) + { + if (WSAGetLastError() != WSAEWOULDBLOCK) + { closesocket(self->fd); self->fd = INVALID_SOCKET; return false; @@ -439,21 +463,25 @@ Socket_checkAsyncConnectState(Socket self) FD_ZERO(&fdSet); FD_SET(self->fd, &fdSet); - int selectVal = select(self->fd + 1, NULL, &fdSet , NULL, &timeout); + int selectVal = select(self->fd + 1, NULL, &fdSet, NULL, &timeout); - if (selectVal == 1) { + if (selectVal == 1) + { /* Check if connection is established */ int so_error; int len = sizeof so_error; - if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, (char*) (&so_error), &len) != SOCKET_ERROR) { - if (so_error == 0) { + if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, (char*)(&so_error), &len) != SOCKET_ERROR) + { + if (so_error == 0) + { int recvRes = recv(self->fd, NULL, 0, 0); - if (recvRes == SOCKET_ERROR) { + if (recvRes == SOCKET_ERROR) + { int wsaError = WSAGetLastError(); if (wsaError == WSAECONNRESET) @@ -463,17 +491,18 @@ Socket_checkAsyncConnectState(Socket self) return SOCKET_STATE_FAILED; } - return SOCKET_STATE_CONNECTED; } } return SOCKET_STATE_FAILED; } - else if (selectVal == 0) { + else if (selectVal == 0) + { return SOCKET_STATE_CONNECTING; } - else { + else + { return SOCKET_STATE_FAILED; } } @@ -492,21 +521,23 @@ Socket_connect(Socket self, const char* address, int port) FD_ZERO(&fdSet); FD_SET(self->fd, &fdSet); - if (select(self->fd + 1, NULL, &fdSet , NULL, &timeout) == 1) { + if (select(self->fd + 1, NULL, &fdSet, NULL, &timeout) == 1) + { /* Check if connection is established */ int so_error; socklen_t len = sizeof so_error; - if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, (char*)&so_error, &len) >= 0) { + if (getsockopt(self->fd, SOL_SOCKET, SO_ERROR, (char*)&so_error, &len) >= 0) + { if (so_error == 0) return true; } } - closesocket (self->fd); + closesocket(self->fd); self->fd = INVALID_SOCKET; return false; @@ -521,26 +552,28 @@ convertAddressToStr(struct sockaddr_storage* addr) bool isIPv6; - if (addr->ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) addr; + if (addr->ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)addr; port = ntohs(ipv4Addr->sin_port); ipv4Addr->sin_port = 0; - WSAAddressToString((LPSOCKADDR) ipv4Addr, sizeof(struct sockaddr_storage), NULL, - (LPSTR) addrString, (LPDWORD) &addrStringLen); + WSAAddressToString((LPSOCKADDR)ipv4Addr, sizeof(struct sockaddr_storage), NULL, (LPSTR)addrString, + (LPDWORD)&addrStringLen); isIPv6 = false; } - else if (addr->ss_family == AF_INET6){ - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) addr; + else if (addr->ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)addr; port = ntohs(ipv6Addr->sin6_port); ipv6Addr->sin6_port = 0; - WSAAddressToString((LPSOCKADDR) ipv6Addr, sizeof(struct sockaddr_storage), NULL, - (LPSTR) addrString, (LPDWORD) &addrStringLen); + WSAAddressToString((LPSOCKADDR)ipv6Addr, sizeof(struct sockaddr_storage), NULL, (LPSTR)addrString, + (LPDWORD)&addrStringLen); isIPv6 = true; } else return NULL; - char* clientConnection = (char*) GLOBAL_MALLOC(strlen(addrString) + 9); + char* clientConnection = (char*)GLOBAL_MALLOC(strlen(addrString) + 9); if (isIPv6) sprintf(clientConnection, "[%s]:%i", addrString, port); @@ -550,14 +583,14 @@ convertAddressToStr(struct sockaddr_storage* addr) return clientConnection; } - char* Socket_getPeerAddress(Socket self) { struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); - if (getpeername(self->fd, (struct sockaddr*) &addr, &addrLen) == 0) { + if (getpeername(self->fd, (struct sockaddr*)&addr, &addrLen) == 0) + { return convertAddressToStr(&addr); } else @@ -570,7 +603,8 @@ Socket_getLocalAddress(Socket self) struct sockaddr_storage addr; socklen_t addrLen = sizeof(addr); - if (getsockname(self->fd, (struct sockaddr*) &addr, &addrLen) == 0) { + if (getsockname(self->fd, (struct sockaddr*)&addr, &addrLen) == 0) + { return convertAddressToStr(&addr); } else @@ -583,7 +617,7 @@ Socket_getPeerAddressStatic(Socket self, char* peerAddressString) struct sockaddr_storage addr; int addrLen = sizeof(addr); - getpeername(self->fd, (struct sockaddr*) &addr, &addrLen); + getpeername(self->fd, (struct sockaddr*)&addr, &addrLen); char addrString[INET6_ADDRSTRLEN + 7]; int addrStringLen = INET6_ADDRSTRLEN + 7; @@ -591,20 +625,22 @@ Socket_getPeerAddressStatic(Socket self, char* peerAddressString) bool isIPv6; - if (addr.ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &addr; + if (addr.ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)&addr; port = ntohs(ipv4Addr->sin_port); ipv4Addr->sin_port = 0; - WSAAddressToString((LPSOCKADDR) ipv4Addr, sizeof(struct sockaddr_storage), NULL, - (LPSTR) addrString, (LPDWORD) & addrStringLen); + WSAAddressToString((LPSOCKADDR)ipv4Addr, sizeof(struct sockaddr_storage), NULL, (LPSTR)addrString, + (LPDWORD)&addrStringLen); isIPv6 = false; } - else if (addr.ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &addr; + else if (addr.ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)&addr; port = ntohs(ipv6Addr->sin6_port); ipv6Addr->sin6_port = 0; - WSAAddressToString((LPSOCKADDR) ipv6Addr, sizeof(struct sockaddr_storage), NULL, - (LPSTR) addrString, (LPDWORD) & addrStringLen); + WSAAddressToString((LPSOCKADDR)ipv6Addr, sizeof(struct sockaddr_storage), NULL, (LPSTR)addrString, + (LPDWORD)&addrStringLen); isIPv6 = true; } else @@ -621,12 +657,13 @@ Socket_getPeerAddressStatic(Socket self, char* peerAddressString) int Socket_read(Socket self, uint8_t* buf, int size) { - int bytes_read = recv(self->fd, (char*) buf, size, 0); + int bytes_read = recv(self->fd, (char*)buf, size, 0); if (bytes_read == 0) /* peer has closed socket */ return -1; - if (bytes_read == SOCKET_ERROR) { + if (bytes_read == SOCKET_ERROR) + { if (WSAGetLastError() == WSAEWOULDBLOCK) return 0; else @@ -639,9 +676,10 @@ Socket_read(Socket self, uint8_t* buf, int size) int Socket_write(Socket self, uint8_t* buf, int size) { - int bytes_sent = send(self->fd, (char*) buf, size, 0); + int bytes_sent = send(self->fd, (char*)buf, size, 0); - if (bytes_sent == SOCKET_ERROR) { + if (bytes_sent == SOCKET_ERROR) + { int errorCode = WSAGetLastError(); if (errorCode == WSAEWOULDBLOCK) @@ -656,7 +694,8 @@ Socket_write(Socket self, uint8_t* buf, int size) void Socket_destroy(Socket self) { - if (self->fd != INVALID_SOCKET) { + if (self->fd != INVALID_SOCKET) + { shutdown(self->fd, 2); closesocket(self->fd); @@ -680,23 +719,27 @@ UdpSocket_createUsingNamespace(int ns) SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0); - if (sock != INVALID_SOCKET) { - self = (UdpSocket) GLOBAL_MALLOC(sizeof(struct sSocket)); + if (sock != INVALID_SOCKET) + { + self = (UdpSocket)GLOBAL_MALLOC(sizeof(struct sSocket)); - if (self) { + if (self) + { self->fd = sock; self->ns = ns; } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to allocate memory\n"); closesocket(sock); } } - else { + else + { if (DEBUG_SOCKET) - printf("SOCKET: failed to create UDP socket (errno=%i)\n", WSAGetLastError()); + printf("SOCKET: failed to create UDP socket (errno=%i)\n", WSAGetLastError()); } return self; @@ -717,37 +760,43 @@ UdpSocket_createIpV6() bool UdpSocket_addGroupMembership(UdpSocket self, const char* multicastAddress) { - if (self->ns == AF_INET) { + if (self->ns == AF_INET) + { struct ip_mreq mreq; - if (inet_pton(AF_INET, multicastAddress, &(mreq.imr_multiaddr)) < 1) { + if (inet_pton(AF_INET, multicastAddress, &(mreq.imr_multiaddr)) < 1) + { printf("SOCKET: Invalid IPv4 multicast address\n"); return false; } - else { + else + { mreq.imr_interface.s_addr = htonl(INADDR_ANY); - if (setsockopt(self->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) == -1) { - printf("SOCKET: failed to set IPv4 multicast group (errno: %i)\n", WSAGetLastError()); + if (setsockopt(self->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) == -1) + { + printf("SOCKET: failed to set IPv4 multicast group (errno: %i)\n", WSAGetLastError()); return false; } - } return true; } - else if (self->ns == AF_INET6) { + else if (self->ns == AF_INET6) + { struct ipv6_mreq mreq; - if (inet_pton(AF_INET6, multicastAddress, &(mreq.ipv6mr_multiaddr)) < 1) { - printf("SOCKET: failed to set IPv6 multicast group (errno: %i)\n", WSAGetLastError()); + if (inet_pton(AF_INET6, multicastAddress, &(mreq.ipv6mr_multiaddr)) < 1) + { + printf("SOCKET: failed to set IPv6 multicast group (errno: %i)\n", WSAGetLastError()); return false; } mreq.ipv6mr_interface = 0; - if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) == -1) { - printf("SOCKET: failed to set IPv6 multicast group (errno: %i)\n", WSAGetLastError()); + if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) == -1) + { + printf("SOCKET: failed to set IPv6 multicast group (errno: %i)\n", WSAGetLastError()); return false; } @@ -760,17 +809,21 @@ UdpSocket_addGroupMembership(UdpSocket self, const char* multicastAddress) bool UdpSocket_setMulticastTtl(UdpSocket self, int ttl) { - if (self->ns == AF_INET) { - if (setsockopt(self->fd, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl)) == -1) { - printf("SOCKET: failed to set IPv4 multicast TTL (errno: %i)\n", WSAGetLastError()); + if (self->ns == AF_INET) + { + if (setsockopt(self->fd, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, sizeof(ttl)) == -1) + { + printf("SOCKET: failed to set IPv4 multicast TTL (errno: %i)\n", WSAGetLastError()); return false; } return true; } - else if (self->ns == AF_INET6) { - if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&ttl, sizeof(ttl)) == -1) { - printf("SOCKET: failed to set IPv6 multicast TTL(hops) (errno: %i)\n", WSAGetLastError()); + else if (self->ns == AF_INET6) + { + if (setsockopt(self->fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char*)&ttl, sizeof(ttl)) == -1) + { + printf("SOCKET: failed to set IPv6 multicast TTL(hops) (errno: %i)\n", WSAGetLastError()); return false; } @@ -783,10 +836,11 @@ UdpSocket_setMulticastTtl(UdpSocket self, int ttl) bool UdpSocket_bind(UdpSocket self, const char* address, int port) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_in localAddress; - if (!prepareAddress(address, port, &localAddress)) { + if (!prepareAddress(address, port, &localAddress)) + { closesocket(self->fd); self->fd = 0; return false; @@ -794,7 +848,8 @@ UdpSocket_bind(UdpSocket self, const char* address, int port) int result = bind(self->fd, (struct sockaddr*)&localAddress, sizeof(localAddress)); - if (result == -1) { + if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to bind UDP socket (errno=%i)\n", errno); @@ -810,10 +865,11 @@ UdpSocket_bind(UdpSocket self, const char* address, int port) bool UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, int msgSize) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_in remoteAddress; - if (!prepareAddress(address, port, &remoteAddress)) { + if (!prepareAddress(address, port, &remoteAddress)) + { if (DEBUG_SOCKET) printf("SOCKET: failed to lookup remote address %s\n", address); @@ -821,16 +877,20 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in return false; } - int result = sendto(self->fd, (const char*) msg, msgSize, 0, (struct sockaddr*)&remoteAddress, sizeof(remoteAddress)); + int result = + sendto(self->fd, (const char*)msg, msgSize, 0, (struct sockaddr*)&remoteAddress, sizeof(remoteAddress)); - if (result == msgSize) { + if (result == msgSize) + { return true; } - else if (result == -1) { + else if (result == -1) + { if (DEBUG_SOCKET) printf("SOCKET: failed to send UDP message (errno=%i)\n", errno); } - else { + else + { if (DEBUG_SOCKET) printf("SOCKET: failed to send UDP message (insufficient data sent)\n"); } @@ -841,7 +901,7 @@ UdpSocket_sendTo(UdpSocket self, const char* address, int port, uint8_t* msg, in int UdpSocket_receiveFrom(UdpSocket self, char* address, int maxAddrSize, uint8_t* msg, int msgSize) { - //TODO add support for IPv6 + // TODO add support for IPv6 struct sockaddr_storage remoteAddress; memset(&remoteAddress, 0, sizeof(struct sockaddr_storage)); socklen_t structSize = sizeof(struct sockaddr_storage); @@ -849,31 +909,35 @@ UdpSocket_receiveFrom(UdpSocket self, char* address, int maxAddrSize, uint8_t* m if (address) address[0] = 0; - int result = recvfrom(self->fd, (char*) msg, msgSize, 0, (struct sockaddr*)&remoteAddress, &structSize); + int result = recvfrom(self->fd, (char*)msg, msgSize, 0, (struct sockaddr*)&remoteAddress, &structSize); if (result == 0) /* peer has closed socket */ return -1; - if (result == SOCKET_ERROR) { + if (result == SOCKET_ERROR) + { if (WSAGetLastError() == WSAEWOULDBLOCK) return 0; else return -1; } - if (address) { + if (address) + { bool isIPv6; char addrString[INET6_ADDRSTRLEN + 7]; int port; - if (remoteAddress.ss_family == AF_INET) { - struct sockaddr_in* ipv4Addr = (struct sockaddr_in*) &remoteAddress; + if (remoteAddress.ss_family == AF_INET) + { + struct sockaddr_in* ipv4Addr = (struct sockaddr_in*)&remoteAddress; port = ntohs(ipv4Addr->sin_port); inet_ntop(AF_INET, &(ipv4Addr->sin_addr), addrString, INET_ADDRSTRLEN); isIPv6 = false; } - else if (remoteAddress.ss_family == AF_INET6) { - struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*) &remoteAddress; + else if (remoteAddress.ss_family == AF_INET6) + { + struct sockaddr_in6* ipv6Addr = (struct sockaddr_in6*)&remoteAddress; port = ntohs(ipv6Addr->sin6_port); inet_ntop(AF_INET6, &(ipv6Addr->sin6_addr), addrString, INET6_ADDRSTRLEN); isIPv6 = true; diff --git a/hal/time/unix/time.c b/hal/time/unix/time.c index 8596b6fc..b8975aea 100644 --- a/hal/time/unix/time.c +++ b/hal/time/unix/time.c @@ -1,7 +1,7 @@ /* * time.c * - * Copyright 2013-2021 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of Platform Abstraction Layer (libpal) * for libiec61850, libmms, and lib60870. @@ -62,4 +62,36 @@ Hal_setTimeInNs(nsSinceEpoch nsTime) return true; } +msSinceEpoch +Hal_getMonotonicTimeInMs() +{ + uint64_t timeVal = 0; + + struct timespec ts; + + if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0) + { + timeVal = ((uint64_t)ts.tv_sec * 1000LL) + (ts.tv_nsec / 1000000); + } + + return timeVal; +} + +nsSinceEpoch +Hal_getMonotonicTimeInNs() +{ + uint64_t nsTime = 0; + + struct timespec ts; + + if (clock_gettime(CLOCK_REALTIME, &ts) == 0) + { + nsTime = ts.tv_sec * 1000000000UL; + nsTime += ts.tv_nsec; + } + + return nsTime; +} + #endif + diff --git a/hal/time/win32/time.c b/hal/time/win32/time.c index 25faf710..3a194e51 100644 --- a/hal/time/win32/time.c +++ b/hal/time/win32/time.c @@ -1,7 +1,7 @@ /* * time.c * - * Copyright 2013-2021 Michael Zillgith + * Copyright 2013-2024 Michael Zillgith * * This file is part of Platform Abstraction Layer (libpal) * for libiec61850, libmms, and lib60870. @@ -59,3 +59,14 @@ Hal_setTimeInNs(nsSinceEpoch nsTime) return SetSystemTime(&st); } +msSinceEpoch +Hal_getMonotonicTimeInMs() +{ + return (msSinceEpoch)GetTickCount64; +} + +nsSinceEpoch +Hal_getMonotonicTimeInNs() +{ + return (nsSinceEpoch)(GetTickCount64() * 1000000ULL); +} diff --git a/hal/tls/mbedtls3/tls_mbedtls.c b/hal/tls/mbedtls3/tls_mbedtls.c index ee1edd66..ced463ac 100644 --- a/hal/tls/mbedtls3/tls_mbedtls.c +++ b/hal/tls/mbedtls3/tls_mbedtls.c @@ -11,23 +11,21 @@ #include -#include "tls_socket.h" #include "hal_thread.h" -#include "lib_memory.h" #include "hal_time.h" +#include "lib_memory.h" #include "linked_list.h" +#include "tls_socket.h" -#include "mbedtls/platform.h" -#include "mbedtls/entropy.h" #include "mbedtls/ctr_drbg.h" -// MIGRATE 2.28->3.x.x: https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#remove-the-certs-module-from-the-library -// #include "mbedtls/certs.h" (MIGRATE 2.28->3.x.x) -#include "mbedtls/x509.h" -#include "mbedtls/ssl.h" -#include "mbedtls/net_sockets.h" -#include "mbedtls/error.h" +#include "mbedtls/entropy.h" +#include "mbedtls/platform.h" #include "mbedtls/debug.h" +#include "mbedtls/error.h" +#include "mbedtls/net_sockets.h" +#include "mbedtls/ssl.h" #include "mbedtls/ssl_cache.h" +#include "mbedtls/x509.h" #define SEC_EVENT_ALARM 2 #define SEC_EVENT_WARNING 1 @@ -38,14 +36,18 @@ #endif #if (CONFIG_DEBUG_TLS == 1) -#define DEBUG_PRINT(appId, fmt, ...) fprintf(stderr, "%s: " fmt, appId, ## __VA_ARGS__) +#define DEBUG_PRINT(appId, fmt, ...) fprintf(stderr, "%s: " fmt, appId, ##__VA_ARGS__) #else -#define DEBUG_PRINT(fmt, ...) do {} while(0) +#define DEBUG_PRINT(fmt, ...) \ + do \ + { \ + } while (0) #endif static int psaInitCounter = 0; -struct sTLSConfiguration { +struct sTLSConfiguration +{ mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; @@ -73,11 +75,9 @@ struct sTLSConfiguration { /* TLS session renegotiation interval in milliseconds */ int renegotiationTimeInMs; - // MIGRATE 2.28->3.x.x: Changed min version to 1.2 to reflect the removal of 1.1 and 1.0 /* TLS minimum version allowed (default: TLS_VERSION_TLS_1_2) */ TLSConfigVersion minVersion; - - // MIGRATE 2.28->3.x.x: Kept the max version but changed documentation + /* TLS maximum version allowed (default: TLS_VERSION_NOT_SELECTED) */ TLSConfigVersion maxVersion; @@ -96,7 +96,8 @@ struct sTLSConfiguration { int maxCiphersuites; }; -struct sTLSSocket { +struct sTLSSocket +{ mbedtls_ssl_context ssl; Socket socket; mbedtls_ssl_config conf; @@ -113,20 +114,21 @@ struct sTLSSocket { }; static void -raiseSecurityEvent(TLSConfiguration config, TLSEventLevel eventCategory, int eventCode, const char* message, TLSSocket socket) +raiseSecurityEvent(TLSConfiguration config, TLSEventLevel eventCategory, int eventCode, const char* message, + TLSSocket socket) { - if (config->eventHandler) { + if (config->eventHandler) + { config->eventHandler(config->eventHandlerParameter, eventCategory, eventCode, message, (TLSConnection)socket); } } static bool -compareCertificates(mbedtls_x509_crt *crt1, mbedtls_x509_crt *crt2) +compareCertificates(mbedtls_x509_crt* crt1, mbedtls_x509_crt* crt2) { - // MIGRATE 2.28->3.x.x: https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#most-structure-fields-are-now-private - if (crt1 != NULL && crt2 != NULL && - crt1->raw.len == crt2->raw.len && - memcmp(crt1->raw.p, crt2->raw.p, crt1->raw.len) == 0) { + if (crt1 != NULL && crt2 != NULL && crt1->raw.len == crt2->raw.len && + memcmp(crt1->raw.p, crt2->raw.p, crt1->raw.len) == 0) + { return true; } @@ -134,9 +136,9 @@ compareCertificates(mbedtls_x509_crt *crt1, mbedtls_x509_crt *crt2) } static int -verifyCertificate (void* parameter, mbedtls_x509_crt *crt, int certificate_depth, uint32_t *flags) +verifyCertificate(void* parameter, mbedtls_x509_crt* crt, int certificate_depth, uint32_t* flags) { - TLSSocket self = (TLSSocket) parameter; + TLSSocket self = (TLSSocket)parameter; DEBUG_PRINT("TLS", "Verify cert: depth %i\n", certificate_depth); @@ -166,7 +168,7 @@ verifyCertificate (void* parameter, mbedtls_x509_crt *crt, int certificate_depth while (certList) { - mbedtls_x509_crt* allowedCert = (mbedtls_x509_crt*) LinkedList_getData(certList); + mbedtls_x509_crt* allowedCert = (mbedtls_x509_crt*)LinkedList_getData(certList); DEBUG_PRINT("TLS", "Compare With:\n"); mbedtls_x509_crt_info(buffer, 1023, " ", allowedCert); @@ -188,7 +190,8 @@ verifyCertificate (void* parameter, mbedtls_x509_crt *crt, int certificate_depth } else { - raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_NOT_CONFIGURED, "Alarm: certificate validation: trusted individual certificate not available", self); + raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_NOT_CONFIGURED, + "Alarm: certificate validation: trusted individual certificate not available", self); *flags |= MBEDTLS_X509_BADCERT_OTHER; return 1; @@ -201,28 +204,32 @@ verifyCertificate (void* parameter, mbedtls_x509_crt *crt, int certificate_depth { *flags = *flags - MBEDTLS_X509_BADCERT_EXPIRED; - raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_CERT_EXPIRED, "Warning: certificate validation: using expired certificate", self); + raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_CERT_EXPIRED, + "Warning: certificate validation: using expired certificate", self); } if (*flags & MBEDTLS_X509_BADCRL_EXPIRED) { *flags = *flags - MBEDTLS_X509_BADCRL_EXPIRED; - raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_CRL_EXPIRED, "Warning: certificate validation: using expired CRL", self); + raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_CRL_EXPIRED, + "Warning: certificate validation: using expired CRL", self); } if (*flags & MBEDTLS_X509_BADCERT_FUTURE) { *flags = *flags - MBEDTLS_X509_BADCERT_FUTURE; - raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_CERT_NOT_YET_VALID, "Warning: certificate validation: using certificate with validity in future", self); + raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_CERT_NOT_YET_VALID, + "Warning: certificate validation: using certificate with validity in future", self); } if (*flags & MBEDTLS_X509_BADCRL_FUTURE) { *flags = *flags - MBEDTLS_X509_BADCRL_FUTURE; - raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_CRL_NOT_YET_VALID, "Warning: certificate validation: using CRL with validity in future", self); + raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_CRL_NOT_YET_VALID, + "Warning: certificate validation: using CRL with validity in future", self); } } @@ -231,7 +238,7 @@ verifyCertificate (void* parameter, mbedtls_x509_crt *crt, int certificate_depth if (*flags == 0) { self->peerCertLength = 0; - self->peerCert = (uint8_t*) GLOBAL_MALLOC(crt->raw.len); + self->peerCert = (uint8_t*)GLOBAL_MALLOC(crt->raw.len); if (self->peerCert) { @@ -253,13 +260,14 @@ TLSConfiguration_setupComplete(TLSConfiguration self) { if (self->setupComplete == false) { - mbedtls_ssl_conf_ca_chain( &(self->conf), &(self->cacerts), &(self->crl) ); + mbedtls_ssl_conf_ca_chain(&(self->conf), &(self->cacerts), &(self->crl)); if (self->ownCertificate.version > 0) { - int ret = mbedtls_ssl_conf_own_cert( &(self->conf), &(self->ownCertificate), &(self->ownKey)); + int ret = mbedtls_ssl_conf_own_cert(&(self->conf), &(self->ownCertificate), &(self->ownKey)); - if (ret != 0) { + if (ret != 0) + { DEBUG_PRINT("TLS", "mbedtls_ssl_conf_own_cert returned -0x%x\n", -ret); return false; } @@ -267,19 +275,17 @@ TLSConfiguration_setupComplete(TLSConfiguration self) if (self->useSessionResumption) { - if (mbedtls_ssl_conf_get_endpoint(&(self->conf)) == MBEDTLS_SSL_IS_CLIENT) { - + if (mbedtls_ssl_conf_get_endpoint(&(self->conf)) == MBEDTLS_SSL_IS_CLIENT) + { } else { - mbedtls_ssl_cache_init( &(self->cache) ); - - // MIGRATE 2.28->3.x.x: https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#most-structure-fields-are-now-private + mbedtls_ssl_cache_init(&(self->cache)); + mbedtls_ssl_cache_set_timeout(&(self->cache), self->sessionResumptionInterval); - mbedtls_ssl_conf_session_cache( &(self->conf), &(self->cache), - mbedtls_ssl_cache_get, - mbedtls_ssl_cache_set ); + mbedtls_ssl_conf_session_cache(&(self->conf), &(self->cache), mbedtls_ssl_cache_get, + mbedtls_ssl_cache_set); } } @@ -344,31 +350,36 @@ TLSConfiguration_clearCipherSuiteList(TLSConfiguration self) TLSConfiguration TLSConfiguration_create() { - TLSConfiguration self = (TLSConfiguration) GLOBAL_CALLOC(1, sizeof(struct sTLSConfiguration)); + TLSConfiguration self = (TLSConfiguration)GLOBAL_CALLOC(1, sizeof(struct sTLSConfiguration)); if (self) { /* call to psa_crypto_init required -> see https://github.com/Mbed-TLS/mbedtls/issues/9223 */ - psa_status_t psaStatus = psa_crypto_init(); + psa_status_t psaStatus = psa_crypto_init(); + + if (psaStatus != PSA_SUCCESS) + { + DEBUG_PRINT("TLS", "psa_crypto_init failed with %i\n", psaStatus); + GLOBAL_FREEMEM(self); + return NULL; + } psaInitCounter++; - mbedtls_ssl_config_init( &(self->conf) ); - mbedtls_x509_crt_init( &(self->ownCertificate) ); - mbedtls_x509_crt_init( &(self->cacerts) ); - mbedtls_x509_crl_init( &(self->crl) ); - mbedtls_pk_init( &(self->ownKey) ); - mbedtls_entropy_init( &(self->entropy) ); - mbedtls_ctr_drbg_init( &(self->ctr_drbg) ); + mbedtls_ssl_config_init(&(self->conf)); + mbedtls_x509_crt_init(&(self->ownCertificate)); + mbedtls_x509_crt_init(&(self->cacerts)); + mbedtls_x509_crl_init(&(self->crl)); + mbedtls_pk_init(&(self->ownKey)); + mbedtls_entropy_init(&(self->entropy)); + mbedtls_ctr_drbg_init(&(self->ctr_drbg)); /* WARINING is fixed to server! */ - mbedtls_ssl_config_defaults( &(self->conf), - MBEDTLS_SSL_IS_SERVER, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT ); + mbedtls_ssl_config_defaults(&(self->conf), MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT); - mbedtls_ctr_drbg_seed( &(self->ctr_drbg), mbedtls_entropy_func, &(self->entropy), NULL, 0); - mbedtls_ssl_conf_rng( &(self->conf), mbedtls_ctr_drbg_random, &(self->ctr_drbg) ); + mbedtls_ctr_drbg_seed(&(self->ctr_drbg), mbedtls_entropy_func, &(self->entropy), NULL, 0); + mbedtls_ssl_conf_rng(&(self->conf), mbedtls_ctr_drbg_random, &(self->ctr_drbg)); mbedtls_ssl_conf_authmode(&(self->conf), MBEDTLS_SSL_VERIFY_REQUIRED); @@ -408,13 +419,15 @@ TLSConfiguration_create() /* mandatory cipher suites by IEC 62351-4:2018 */ self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256; - /* self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_DH_RSA_WITH_AES_128_GCM_SHA256; */ /* weak - not supported? */ + /* self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_DH_RSA_WITH_AES_128_GCM_SHA256; */ /* weak - not + supported? */ self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256; self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; /* recommended cipher suites by IEC 62351-4:2018 */ - /* self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_DH_RSA_WITH_AES_128_CBC_SHA256; */ /* weak - not supported?*/ + /* self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_DH_RSA_WITH_AES_128_CBC_SHA256; */ /* weak - not + supported?*/ /* self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_DH_RSA_WITH_AES_256_GCM_SHA384; */ /* not supported?*/ self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256; self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384; @@ -425,11 +438,16 @@ TLSConfiguration_create() self->ciphersuites[cipherIndex++] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384; /* TLS 1.3 cipher suites */ - self->ciphersuites[cipherIndex++] = MBEDTLS_TLS1_3_AES_128_GCM_SHA256; /* mandatory according IEC 62351-3:2023 */ - self->ciphersuites[cipherIndex++] = MBEDTLS_TLS1_3_AES_256_GCM_SHA384; /* mandatory according IEC 62351-3:2023 */ - self->ciphersuites[cipherIndex++] = MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256; /* optional according IEC 62351-3:2023 */ - self->ciphersuites[cipherIndex++] = MBEDTLS_TLS1_3_AES_128_CCM_SHA256; /* mandatory according IEC 62351-3:2023 */ - self->ciphersuites[cipherIndex++] = MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256 ; /* optional according IEC 62351-3:2023 */ + self->ciphersuites[cipherIndex++] = + MBEDTLS_TLS1_3_AES_128_GCM_SHA256; /* mandatory according IEC 62351-3:2023 */ + self->ciphersuites[cipherIndex++] = + MBEDTLS_TLS1_3_AES_256_GCM_SHA384; /* mandatory according IEC 62351-3:2023 */ + self->ciphersuites[cipherIndex++] = + MBEDTLS_TLS1_3_CHACHA20_POLY1305_SHA256; /* optional according IEC 62351-3:2023 */ + self->ciphersuites[cipherIndex++] = + MBEDTLS_TLS1_3_AES_128_CCM_SHA256; /* mandatory according IEC 62351-3:2023 */ + self->ciphersuites[cipherIndex++] = + MBEDTLS_TLS1_3_AES_128_CCM_8_SHA256; /* optional according IEC 62351-3:2023 */ } } @@ -505,7 +523,7 @@ TLSConfiguration_setOwnCertificate(TLSConfiguration self, uint8_t* certificate, bool TLSConfiguration_setOwnCertificateFromFile(TLSConfiguration self, const char* filename) { - int ret = mbedtls_x509_crt_parse_file(&(self->ownCertificate), filename); + int ret = mbedtls_x509_crt_parse_file(&(self->ownCertificate), filename); if (ret != 0) DEBUG_PRINT("TLS", "mbedtls_x509_crt_parse_file returned -0x%x\n", -ret); @@ -516,9 +534,9 @@ TLSConfiguration_setOwnCertificateFromFile(TLSConfiguration self, const char* fi bool TLSConfiguration_setOwnKey(TLSConfiguration self, uint8_t* key, int keyLen, const char* keyPassword) { - // MIGRATE 2.28->3.x.x: https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#some-functions-gained-an-rng-parameter - // MIGRATE 2.28->3.x.x: drbg needs to be initialized, but it seems to be done in TLSConfiguration_create - int ret = mbedtls_pk_parse_key(&(self->ownKey), key, keyLen, (const uint8_t*) keyPassword, (keyPassword == NULL) ? 0 : strlen(keyPassword), mbedtls_ctr_drbg_random, &(self->ctr_drbg)); + int ret = mbedtls_pk_parse_key(&(self->ownKey), key, keyLen, (const uint8_t*)keyPassword, + (keyPassword == NULL) ? 0 : strlen(keyPassword), mbedtls_ctr_drbg_random, + &(self->ctr_drbg)); if (ret != 0) DEBUG_PRINT("TLS", "mbedtls_pk_parse_key returned -0x%x\n", -ret); @@ -529,9 +547,8 @@ TLSConfiguration_setOwnKey(TLSConfiguration self, uint8_t* key, int keyLen, cons bool TLSConfiguration_setOwnKeyFromFile(TLSConfiguration self, const char* filename, const char* keyPassword) { - // MIGRATE 2.28->3.x.x: https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#some-functions-gained-an-rng-parameter - // MIGRATE 2.28->3.x.x: drbg needs to be initialized, but it seems to be done in TLSConfiguration_create - int ret = mbedtls_pk_parse_keyfile(&(self->ownKey), filename, keyPassword, mbedtls_ctr_drbg_random, &(self->ctr_drbg)); + int ret = + mbedtls_pk_parse_keyfile(&(self->ownKey), filename, keyPassword, mbedtls_ctr_drbg_random, &(self->ctr_drbg)); if (ret != 0) DEBUG_PRINT("TLS", "mbedtls_pk_parse_keyfile returned -0x%x\n", -ret); @@ -542,7 +559,7 @@ TLSConfiguration_setOwnKeyFromFile(TLSConfiguration self, const char* filename, bool TLSConfiguration_addAllowedCertificate(TLSConfiguration self, uint8_t* certificate, int certLen) { - mbedtls_x509_crt* cert = (mbedtls_x509_crt*) GLOBAL_CALLOC(1, sizeof(mbedtls_x509_crt)); + mbedtls_x509_crt* cert = (mbedtls_x509_crt*)GLOBAL_CALLOC(1, sizeof(mbedtls_x509_crt)); int ret = mbedtls_x509_crt_parse(cert, certificate, certLen); @@ -561,7 +578,7 @@ TLSConfiguration_addAllowedCertificate(TLSConfiguration self, uint8_t* certifica bool TLSConfiguration_addAllowedCertificateFromFile(TLSConfiguration self, const char* filename) { - mbedtls_x509_crt* cert = (mbedtls_x509_crt*) GLOBAL_CALLOC(1, sizeof(mbedtls_x509_crt)); + mbedtls_x509_crt* cert = (mbedtls_x509_crt*)GLOBAL_CALLOC(1, sizeof(mbedtls_x509_crt)); int ret = mbedtls_x509_crt_parse_file(cert, filename); @@ -580,7 +597,7 @@ TLSConfiguration_addAllowedCertificateFromFile(TLSConfiguration self, const char bool TLSConfiguration_addCACertificate(TLSConfiguration self, uint8_t* certificate, int certLen) { - int ret = mbedtls_x509_crt_parse(&(self->cacerts), certificate, certLen); + int ret = mbedtls_x509_crt_parse(&(self->cacerts), certificate, certLen); if (ret != 0) { @@ -594,7 +611,7 @@ TLSConfiguration_addCACertificate(TLSConfiguration self, uint8_t* certificate, i bool TLSConfiguration_addCACertificateFromFile(TLSConfiguration self, const char* filename) { - int ret = mbedtls_x509_crt_parse_file(&(self->cacerts), filename); + int ret = mbedtls_x509_crt_parse_file(&(self->cacerts), filename); if (ret != 0) DEBUG_PRINT("TLS", "mbedtls_x509_crt_parse returned -0x%x\n", -ret); @@ -622,10 +639,12 @@ TLSConfiguration_addCRL(TLSConfiguration self, uint8_t* crl, int crlLen) { int ret = mbedtls_x509_crl_parse(&(self->crl), crl, crlLen); - if (ret != 0) { + if (ret != 0) + { DEBUG_PRINT("TLS", "mbedtls_x509_crl_parse returned -0x%x\n", -ret); } - else { + else + { udpatedCRL(self); } @@ -635,12 +654,14 @@ TLSConfiguration_addCRL(TLSConfiguration self, uint8_t* crl, int crlLen) bool TLSConfiguration_addCRLFromFile(TLSConfiguration self, const char* filename) { - int ret = mbedtls_x509_crl_parse_file(&(self->crl), filename); + int ret = mbedtls_x509_crl_parse_file(&(self->crl), filename); - if (ret != 0) { + if (ret != 0) + { DEBUG_PRINT("TLS", "mbedtls_x509_crl_parse_file returned %d\n", ret); } - else { + else + { udpatedCRL(self); } @@ -694,7 +715,7 @@ TLSConfiguration_destroy(TLSConfiguration self) while (certElem) { - mbedtls_x509_crt* cert = (mbedtls_x509_crt*) LinkedList_getData(certElem); + mbedtls_x509_crt* cert = (mbedtls_x509_crt*)LinkedList_getData(certElem); mbedtls_x509_crt_free(cert); @@ -720,111 +741,136 @@ createSecurityEvents(TLSConfiguration config, int ret, uint32_t flags, TLSSocket if (config->eventHandler == NULL) return; - switch (ret) { + switch (ret) + { case MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG: - raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_NO_CIPHER, "Alarm: Algorithm not supported", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_NO_CIPHER, "Alarm: Algorithm not supported", + socket); break; - // MIGRATE 2.28->3.x.x:https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#changes-in-the-ssl-error-code-space - // case MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN: (MIGRATE 2.28->3.x.x) - // raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_NO_CIPHER, "Alarm: no matching TLS ciphers", socket); - // break; - - // case MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE: (MIGRATE 2.28->3.x.x) - // raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_ALGO_NOT_SUPPORTED, "Alarm: Algorithm not supported", socket); - // break; + // MIGRATE 2.28->3.x.x:https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#changes-in-the-ssl-error-code-space + // case MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN: (MIGRATE 2.28->3.x.x) + // raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_NO_CIPHER, "Alarm: no matching TLS + // ciphers", socket); break; + // case MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE: (MIGRATE 2.28->3.x.x) + // raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_ALGO_NOT_SUPPORTED, "Alarm: Algorithm + // not supported", socket); break; case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE: - raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_ALGO_NOT_SUPPORTED, "Alarm: Handshake failure", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_ALGO_NOT_SUPPORTED, + "Alarm: Handshake failure", socket); break; - // case MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION: (MIGRATE 2.28->3.x.x) - // raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_UNSECURE_COMMUNICATION, "Alarm: Unsecure communication", socket); - // break; + // case MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION: (MIGRATE 2.28->3.x.x) + // raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_UNSECURE_COMMUNICATION, "Alarm: + // Unsecure communication", socket); break; case MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_UNAVAILABLE, "Alarm: certificate unavailable", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_UNAVAILABLE, + "Alarm: certificate unavailable", socket); break; - // case MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE: (MIGRATE 2.28->3.x.x) - // raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_BAD_CERT, "Alarm: Bad certificate", socket); - // break; + // case MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE: (MIGRATE 2.28->3.x.x) + // raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_BAD_CERT, "Alarm: Bad certificate", + // socket); break; case MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_SIZE_EXCEEDED, "Alarm: TLS certificate size exceeded", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_SIZE_EXCEEDED, + "Alarm: TLS certificate size exceeded", socket); break; - // MIGRATE 2.28->3.x.x: the removal of this is undocumented TODO: Verify migration path - // case MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED: (MIGRATE 2.28->3.x.x) - // raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED, "Alarm: certificate validation: certificate signature could not be validated", socket); - // break; + // MIGRATE 2.28->3.x.x: the removal of this is undocumented TODO: Verify migration path + // case MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED: (MIGRATE 2.28->3.x.x) + // raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED, "Alarm: + // certificate validation: certificate signature could not be validated", socket); break; - // MIGRATE 2.28->3.x.x: the removal of this is undocumented. The docs say migrating users are affected but don't provide a migration path TODO: Verify migration path (MIGRATE 2.28->3.x.x) - // case MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED: - // raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_REQUIRED, "Alarm: Certificate required", socket); - // break; + // MIGRATE 2.28->3.x.x: the removal of this is undocumented. The docs say migrating users are affected but don't + // provide a migration path TODO: Verify migration path (MIGRATE 2.28->3.x.x) case + // MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED: + // raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_REQUIRED, "Alarm: Certificate + // required", socket); break; case MBEDTLS_ERR_SSL_DECODE_ERROR: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: Decode error", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: Decode error", socket); break; - + case MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: Illegal parameter", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: Illegal parameter", socket); break; case MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: Bad protocol version", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: Bad protocol version", socket); break; case MBEDTLS_ERR_SSL_BAD_CERTIFICATE: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: Bad certificate", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: Bad certificate", socket); break; - + case MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: Unrecognized name", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: Unrecognized name", socket); break; - + case MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: Unsupported extension", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: Unsupported extension", socket); break; - + case MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: No application protocol", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: No application protocol", socket); break; case MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: Unexpected message", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: Unexpected message", socket); break; case MBEDTLS_ERR_SSL_INTERNAL_ERROR: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: Internal error", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: Internal error", socket); break; - case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED: + case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED: { + if (flags & MBEDTLS_X509_BADCERT_EXPIRED) { - if (flags & MBEDTLS_X509_BADCERT_EXPIRED) { - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_EXPIRED, "Alarm: expired certificate", socket); - } - else if (flags & MBEDTLS_X509_BADCERT_REVOKED) { - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_REVOKED, "Alarm: revoked certificate", socket); - } - else if (flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) { - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_NOT_TRUSTED, "Alarm: Certificate validation: CA certificate not available", socket); - } - else if (flags & MBEDTLS_X509_BADCERT_OTHER) { - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_NOT_CONFIGURED, "Alarm: Certificate not configured", socket); - } - else if (flags & MBEDTLS_X509_BADCERT_BAD_KEY) { - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_NOT_CONFIGURED, "Alarm: Insufficient key length", socket); - } - - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED, "Alarm: Certificate verification failed", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_EXPIRED, + "Alarm: expired certificate", socket); + } + else if (flags & MBEDTLS_X509_BADCERT_REVOKED) + { + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_REVOKED, + "Alarm: revoked certificate", socket); + } + else if (flags & MBEDTLS_X509_BADCERT_NOT_TRUSTED) + { + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_NOT_TRUSTED, + "Alarm: Certificate validation: CA certificate not available", socket); + } + else if (flags & MBEDTLS_X509_BADCERT_OTHER) + { + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_NOT_CONFIGURED, + "Alarm: Certificate not configured", socket); + } + else if (flags & MBEDTLS_X509_BADCERT_BAD_KEY) + { + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_NOT_CONFIGURED, + "Alarm: Insufficient key length", socket); } - break; + + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_CERT_VALIDATION_FAILED, + "Alarm: Certificate verification failed", socket); + } + break; default: - raiseSecurityEvent(config,TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, "Alarm: handshake failed for unknown reason", socket); + raiseSecurityEvent(config, TLS_SEC_EVT_INCIDENT, TLS_EVENT_CODE_ALM_HANDSHAKE_FAILED_UNKNOWN_REASON, + "Alarm: handshake failed for unknown reason", socket); break; } } @@ -832,7 +878,7 @@ createSecurityEvents(TLSConfiguration config, int ret, uint32_t flags, TLSSocket static int readFunction(void* ctx, unsigned char* buf, size_t len) { - int ret = Socket_read((Socket) ctx, buf, (int)len); + int ret = Socket_read((Socket)ctx, buf, (int)len); if ((ret == 0) && (len > 0)) { @@ -855,37 +901,11 @@ writeFunction(void* ctx, unsigned char* buf, size_t len) return ret; } -static TLSConfigVersion -getTLSVersion(int majorVersion, int minorVersion) -{ - if (majorVersion != 3) { - return TLS_VERSION_NOT_SELECTED; - } - else - { - switch (minorVersion) { - /* TODO: Remove from here (MIGRATE 2.28->3.x.x) */ - case 0: - return TLS_VERSION_SSL_3_0; - case 1: - return TLS_VERSION_TLS_1_0; - case 2: - return TLS_VERSION_TLS_1_1; - /* Up until here (MIGRATE 2.28->3.x.x) */ - case 3: - return TLS_VERSION_TLS_1_2; - case 4: - return TLS_VERSION_TLS_1_3; - default: - return TLS_VERSION_NOT_SELECTED; - } - } -} - static int getMajorVersion(TLSConfigVersion version) { - switch(version) { + switch (version) + { case TLS_VERSION_NOT_SELECTED: return 0; /* TODO: Remove from here (MIGRATE 2.28->3.x.x) */ @@ -904,7 +924,8 @@ getMajorVersion(TLSConfigVersion version) static int getMinorVersion(TLSConfigVersion version) { - switch(version) { + switch (version) + { case TLS_VERSION_NOT_SELECTED: return 0; /* TODO: Remove from here (MIGRATE 2.28->3.x.x) */ @@ -927,7 +948,7 @@ getMinorVersion(TLSConfigVersion version) TLSSocket TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClientCert) { - TLSSocket self = (TLSSocket) GLOBAL_CALLOC(1, sizeof(struct sTLSSocket)); + TLSSocket self = (TLSSocket)GLOBAL_CALLOC(1, sizeof(struct sTLSSocket)); if (self) { @@ -941,11 +962,11 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient memcpy(&(self->conf), &(configuration->conf), sizeof(mbedtls_ssl_config)); - mbedtls_ssl_conf_verify(&(self->conf), verifyCertificate, (void*) self); + mbedtls_ssl_conf_verify(&(self->conf), verifyCertificate, (void*)self); int ret; - mbedtls_ssl_conf_ca_chain( &(self->conf), &(configuration->cacerts), &(configuration->crl) ); + mbedtls_ssl_conf_ca_chain(&(self->conf), &(configuration->cacerts), &(configuration->crl)); self->crlUpdated = configuration->crlUpdated; @@ -956,7 +977,7 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient int majorVer = getMajorVersion(configuration->minVersion); int minorVer = getMinorVersion(configuration->minVersion); - mbedtls_ssl_conf_min_version( &(self->conf), majorVer, minorVer); + mbedtls_ssl_conf_min_version(&(self->conf), majorVer, minorVer); } if (configuration->maxVersion != TLS_VERSION_NOT_SELECTED) @@ -966,24 +987,24 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient int majorVer = getMajorVersion(configuration->maxVersion); int minorVer = getMinorVersion(configuration->maxVersion); - mbedtls_ssl_conf_max_version( &(self->conf), majorVer, minorVer); + mbedtls_ssl_conf_max_version(&(self->conf), majorVer, minorVer); } if (configuration->ownCertificate.version > 0) { - ret = mbedtls_ssl_conf_own_cert( &(self->conf), &(configuration->ownCertificate), &(configuration->ownKey)); + ret = mbedtls_ssl_conf_own_cert(&(self->conf), &(configuration->ownCertificate), &(configuration->ownKey)); if (ret != 0) DEBUG_PRINT("TLS", "mbedtls_ssl_conf_own_cert returned %d\n", ret); } - ret = mbedtls_ssl_setup( &(self->ssl), &(self->conf) ); + ret = mbedtls_ssl_setup(&(self->ssl), &(self->conf)); if (ret != 0) DEBUG_PRINT("TLS", "mbedtls_ssl_setup returned %d\n", ret); - mbedtls_ssl_set_bio(&(self->ssl), socket, (mbedtls_ssl_send_t*) writeFunction, - (mbedtls_ssl_recv_t*) readFunction, NULL); + mbedtls_ssl_set_bio(&(self->ssl), socket, (mbedtls_ssl_send_t*)writeFunction, (mbedtls_ssl_recv_t*)readFunction, + NULL); if (configuration->useSessionResumption) { @@ -991,7 +1012,8 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient { if (configuration->savedSession && configuration->savedSessionTime > 0) { - if (Hal_getTimeInMs() < (configuration->savedSessionTime + configuration->sessionResumptionInterval * 1000)) + if (Hal_getTimeInMs() < + (configuration->savedSessionTime + configuration->sessionResumptionInterval * 1000)) { ret = mbedtls_ssl_set_session(&(self->ssl), configuration->savedSession); @@ -1014,11 +1036,11 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient } } - while( (ret = mbedtls_ssl_handshake(&(self->ssl)) ) != 0 ) + while ((ret = mbedtls_ssl_handshake(&(self->ssl))) != 0) { - if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE ) + if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { - DEBUG_PRINT("TLS", "handshake failed - mbedtls_ssl_handshake returned -0x%x\n", -ret ); + DEBUG_PRINT("TLS", "handshake failed - mbedtls_ssl_handshake returned -0x%x\n", -ret); uint32_t flags = mbedtls_ssl_get_verify_result(&(self->ssl)); @@ -1026,7 +1048,8 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient mbedtls_ssl_free(&(self->ssl)); - if (self->peerCert) { + if (self->peerCert) + { GLOBAL_FREEMEM(self->peerCert); } @@ -1066,11 +1089,6 @@ TLSSocket_create(Socket socket, TLSConfiguration configuration, bool storeClient self->lastRenegotiationTime = Hal_getTimeInMs(); - // MIGRATE 2.28->3.x.x: impossible since mbedtls 3.x.x doesn't support insecure TLS versions - // if (getTLSVersion(self->ssl.major_ver, self->ssl.minor_ver) < TLS_VERSION_TLS_1_2) { - // raiseSecurityEvent(configuration, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_INSECURE_TLS_VERSION, "Warning: Insecure TLS version", self); - // } - /* create event that TLS session is established */ { char msg[256]; @@ -1103,21 +1121,19 @@ TLSSocket_performHandshake(TLSSocket self) if (ret == 0 || ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE || ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS || ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) { - // MIGRATE 2.28->3.x.x: impossible since mbedtls 3.x.x doesn't support insecure TLS versions - // if (getTLSVersion(self->ssl.major_ver, self->ssl.minor_ver) < TLS_VERSION_TLS_1_2) { - // raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_WARNING, TLS_EVENT_CODE_WRN_INSECURE_TLS_VERSION, "Warning: Insecure TLS version", self); - // } - return true; } - else { + else + { DEBUG_PRINT("TLS", "TLSSocket_performHandshake failed -> ret=%i\n", ret); - raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_INFO, TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION, "Alarm: Renegotiation failed", self); + raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_INFO, TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION, + "Alarm: Renegotiation failed", self); /* mbedtls_ssl_renegotiate mandates to reset the ssl session in case of errors */ ret = mbedtls_ssl_session_reset(&(self->ssl)); - if (ret != 0) { + if (ret != 0) + { DEBUG_PRINT("TLS", "mbedtls_ssl_session_reset failed -> ret: -0x%X\n", -ret); } @@ -1133,7 +1149,7 @@ checkForCRLUpdate(TLSSocket self) DEBUG_PRINT("TLS", "CRL updated -> refresh CA chain\n"); - mbedtls_ssl_conf_ca_chain( &(self->conf), &( self->tlsConfig->cacerts), &( self->tlsConfig->crl) ); + mbedtls_ssl_conf_ca_chain(&(self->conf), &(self->tlsConfig->cacerts), &(self->tlsConfig->crl)); self->crlUpdated = self->tlsConfig->crlUpdated; @@ -1148,18 +1164,29 @@ startRenegotiationIfRequired(TLSSocket self) if (self->tlsConfig->renegotiationTimeInMs <= 0) return true; + if (self->lastRenegotiationTime == UINT64_MAX) + return true; + + if (TLSConnection_getTLSVersion((TLSConnection)(self)) == TLS_VERSION_TLS_1_3) + { + self->lastRenegotiationTime = UINT64_MAX; + DEBUG_PRINT("TLS", "renegotiation not allowed for TLS 1.3\n"); + return true; + } + if (Hal_getTimeInMs() <= self->lastRenegotiationTime + self->tlsConfig->renegotiationTimeInMs) return true; - raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_INFO, TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION, "Info: session renegotiation started", self); + raiseSecurityEvent(self->tlsConfig, TLS_SEC_EVT_INFO, TLS_EVENT_CODE_INF_SESSION_RENEGOTIATION, + "Info: session renegotiation started", self); if (TLSSocket_performHandshake(self) == false) { - DEBUG_PRINT("TLS", " renegotiation failed\n"); + DEBUG_PRINT("TLS", "renegotiation failed\n"); return false; } - DEBUG_PRINT("TLS", " started renegotiation\n"); + DEBUG_PRINT("TLS", "started renegotiation\n"); self->lastRenegotiationTime = Hal_getTimeInMs(); return true; @@ -1170,7 +1197,8 @@ TLSSocket_read(TLSSocket self, uint8_t* buf, int size) { checkForCRLUpdate(self); - if (startRenegotiationIfRequired(self) == false) { + if (startRenegotiationIfRequired(self) == false) + { return -1; } @@ -1179,8 +1207,8 @@ TLSSocket_read(TLSSocket self, uint8_t* buf, int size) if ((ret == MBEDTLS_ERR_SSL_WANT_READ) || (ret == MBEDTLS_ERR_SSL_WANT_WRITE)) return 0; - if (ret < 0) { - + if (ret < 0) + { switch (ret) { case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: @@ -1214,22 +1242,26 @@ TLSSocket_write(TLSSocket self, uint8_t* buf, int size) checkForCRLUpdate(self); - if (startRenegotiationIfRequired(self) == false) { + if (startRenegotiationIfRequired(self) == false) + { return -1; } while (len < size) { - int ret = mbedtls_ssl_write(&(self->ssl), (buf + len), (size -len)); + int ret = mbedtls_ssl_write(&(self->ssl), (buf + len), (size - len)); if ((ret == MBEDTLS_ERR_SSL_WANT_READ) || (ret == MBEDTLS_ERR_SSL_WANT_WRITE) || - (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) || (ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS)) { + (ret == MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS) || (ret == MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS)) + { continue; } - if (ret < 0) { + if (ret < 0) + { DEBUG_PRINT("TLS", "mbedtls_ssl_write returned -0x%X\n", -ret); - if (0 != (ret = mbedtls_ssl_session_reset(&(self->ssl)))) { + if (0 != (ret = mbedtls_ssl_session_reset(&(self->ssl)))) + { DEBUG_PRINT("TLS", "mbedtls_ssl_session_reset failed -0x%X\n", -ret); } @@ -1273,14 +1305,15 @@ TLSConnection_getPeerAddress(TLSConnection self, char* peerAddrBuf) { TLSSocket socket = (TLSSocket)self; - if (peerAddrBuf == NULL) { + if (peerAddrBuf == NULL) + { peerAddrBuf = (char*)GLOBAL_MALLOC(61); } if (peerAddrBuf) return Socket_getPeerAddressStatic(socket->socket, peerAddrBuf); else - return NULL; + return NULL; } uint8_t* @@ -1295,17 +1328,18 @@ TLSConfigVersion TLSConnection_getTLSVersion(TLSConnection self) { TLSSocket socket = (TLSSocket)self; - // MIGRATE 2.28->3.x.x: https://github.com/Mbed-TLS/mbedtls/blob/development/docs/3.0-migration-guide.md#most-structure-fields-are-now-private + mbedtls_ssl_protocol_version version = mbedtls_ssl_get_version_number(&(socket->ssl)); - switch(version) { - case MBEDTLS_SSL_VERSION_TLS1_2: - return TLS_VERSION_TLS_1_2; - case MBEDTLS_SSL_VERSION_TLS1_3: - return TLS_VERSION_TLS_1_3; - case MBEDTLS_SSL_VERSION_UNKNOWN: - default: - return TLS_VERSION_NOT_SELECTED; + switch (version) + { + case MBEDTLS_SSL_VERSION_TLS1_2: + return TLS_VERSION_TLS_1_2; + case MBEDTLS_SSL_VERSION_TLS1_3: + return TLS_VERSION_TLS_1_3; + case MBEDTLS_SSL_VERSION_UNKNOWN: + default: + return TLS_VERSION_NOT_SELECTED; } } @@ -1314,19 +1348,19 @@ TLSConfigVersion_toString(TLSConfigVersion version) { switch (version) { - /* TODO: Remove from here (MIGRATE 2.28->3.x.x) */ - case TLS_VERSION_SSL_3_0: - return "SSL 3.0"; - case TLS_VERSION_TLS_1_0: - return "TLS 1.0"; - case TLS_VERSION_TLS_1_1: - return "TLS 1.1"; - /* Up until here (MIGRATE 2.28->3.x.x) */ - case TLS_VERSION_TLS_1_2: - return "TLS 1.2"; - case TLS_VERSION_TLS_1_3: - return "TLS 1.3"; - default: - return "unknown TLS version"; + /* TODO: Remove from here (MIGRATE 2.28->3.x.x) */ + case TLS_VERSION_SSL_3_0: + return "SSL 3.0"; + case TLS_VERSION_TLS_1_0: + return "TLS 1.0"; + case TLS_VERSION_TLS_1_1: + return "TLS 1.1"; + /* Up until here (MIGRATE 2.28->3.x.x) */ + case TLS_VERSION_TLS_1_2: + return "TLS 1.2"; + case TLS_VERSION_TLS_1_3: + return "TLS 1.3"; + default: + return "unknown TLS version"; } }