1 /******************************************************************************* 2 * Copyright (c) 2009, 2022 IBM Corp., Ian Craggs and others 3 * 4 * All rights reserved. This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License v2.0 6 * and Eclipse Distribution License v1.0 which accompany this distribution. 7 * 8 * The Eclipse Public License is available at 9 * https://www.eclipse.org/legal/epl-2.0/ 10 * and the Eclipse Distribution License is available at 11 * http://www.eclipse.org/org/documents/edl-v10.php. 12 * 13 * Contributors: 14 * Ian Craggs - initial implementation and documentation 15 * Ian Craggs - async client updates 16 *******************************************************************************/ 17 18 #if !defined(SOCKET_H) 19 #define SOCKET_H 20 21 #if !defined(IOT_CONNECT) && !defined(IOT_LITEOS_ADAPT) 22 #include <stdint.h> 23 #include <sys/types.h> 24 #endif 25 26 #if defined(_WIN32) || defined(_WIN64) 27 #include <errno.h> 28 #include <winsock2.h> 29 #include <ws2tcpip.h> 30 #define MAXHOSTNAMELEN 256 31 #define poll WSAPoll 32 #if !defined(SSLSOCKET_H) 33 #undef EAGAIN 34 #define EAGAIN WSAEWOULDBLOCK 35 #undef EINTR 36 #define EINTR WSAEINTR 37 #undef EINPROGRESS 38 #define EINPROGRESS WSAEINPROGRESS 39 #undef EWOULDBLOCK 40 #define EWOULDBLOCK WSAEWOULDBLOCK 41 #undef ENOTCONN 42 #define ENOTCONN WSAENOTCONN 43 #undef ECONNRESET 44 #define ECONNRESET WSAECONNRESET 45 #undef ETIMEDOUT 46 #define ETIMEDOUT WAIT_TIMEOUT 47 #endif 48 #define ioctl ioctlsocket 49 #define socklen_t int 50 #else 51 #define INVALID_SOCKET SOCKET_ERROR 52 #include <sys/socket.h> 53 #if !defined(_WRS_KERNEL) 54 #if !defined(IOT_CONNECT) && !defined(IOT_LITEOS_ADAPT) 55 #include <sys/param.h> 56 #endif 57 #include <sys/time.h> 58 #include <sys/select.h> 59 #include <poll.h> 60 #if !defined(IOT_CONNECT) && !defined(IOT_LITEOS_ADAPT) 61 #include <sys/uio.h> 62 #endif 63 #else 64 #include <selectLib.h> 65 #endif 66 #if !defined(IOT_CONNECT) && !defined(IOT_LITEOS_ADAPT) 67 #include <netinet/in.h> 68 #include <netinet/tcp.h> 69 #include <arpa/inet.h> 70 #include <netdb.h> 71 #include <stdio.h> 72 #include <unistd.h> 73 #include <fcntl.h> 74 #include <unistd.h> 75 #endif 76 #include <errno.h> 77 #if defined(IOT_CONNECT) || defined(IOT_LITEOS_ADAPT) 78 extern int errno; 79 #define USE_SELECT 1 80 #endif 81 #define ULONG size_t 82 #define SOCKET int 83 #endif 84 85 #include "mutex_type.h" /* Needed for mutex_type */ 86 87 /** socket operation completed successfully */ 88 #define TCPSOCKET_COMPLETE 0 89 #if !defined(SOCKET_ERROR) 90 /** error in socket operation */ 91 #define SOCKET_ERROR -1 92 #endif 93 /** must be the same as SOCKETBUFFER_INTERRUPTED */ 94 #define TCPSOCKET_INTERRUPTED -22 95 #define SSL_FATAL -3 96 97 #if !defined(INET6_ADDRSTRLEN) 98 #define INET6_ADDRSTRLEN 46 /** only needed for gcc/cygwin on windows */ 99 #endif 100 101 102 #if !defined(max) 103 #define max(A,B) ( (A) > (B) ? (A):(B)) 104 #endif 105 106 #include "LinkedList.h" 107 108 /* 109 * Network write buffers for an MQTT packet 110 */ 111 typedef struct 112 { 113 int count; /**> number of buffers/buflens/frees */ 114 char** buffers; /**> array of byte buffers */ 115 size_t* buflens; /**> array of lengths of buffers */ 116 int* frees; /**> array of flags indicating whether each buffer needs to be freed */ 117 uint8_t mask[4]; /**> websocket mask used to mask the buffer data, if any */ 118 } PacketBuffers; 119 120 121 /** 122 * Structure to hold all socket data for the module 123 */ 124 typedef struct 125 { 126 List* connect_pending; /**< list of sockets for which a connect is pending */ 127 List* write_pending; /**< list of sockets for which a write is pending */ 128 129 #if defined(USE_SELECT) 130 fd_set rset, /**< socket read set (see select doc) */ 131 rset_saved; /**< saved socket read set */ 132 int maxfdp1; /**< max descriptor used +1 (again see select doc) */ 133 List* clientsds; /**< list of client socket descriptors */ 134 ListElement* cur_clientsds; /**< current client socket descriptor (iterator) */ 135 fd_set pending_wset; /**< socket pending write set for select */ 136 #else 137 unsigned int nfds; /**< no of file descriptors for poll */ 138 struct pollfd* fds_read; /**< poll read file descriptors */ 139 struct pollfd* fds_write; 140 141 struct { 142 int cur_fd; /**< index into the fds_saved array */ 143 unsigned int nfds; /**< number of fds in the fds_saved array */ 144 struct pollfd* fds_write; 145 struct pollfd* fds_read; 146 } saved; 147 #endif 148 } Sockets; 149 150 #if defined(IOT_CONNECT) || defined(IOT_LITEOS_ADAPT) 151 int Socket_outInitialize(void); 152 #else 153 void Socket_outInitialize(void); 154 #endif 155 void Socket_outTerminate(void); 156 SOCKET Socket_getReadySocket(int more_work, int timeout, mutex_type mutex, int* rc); 157 int Socket_getch(SOCKET socket, char* c); 158 char *Socket_getdata(SOCKET socket, size_t bytes, size_t* actual_len, int* rc); 159 int Socket_putdatas(SOCKET socket, char* buf0, size_t buf0len, PacketBuffers bufs); 160 int Socket_close(SOCKET socket); 161 #if defined(__GNUC__) && defined(__linux__) && !defined(__LITEOS__) 162 /* able to use GNU's getaddrinfo_a to make timeouts possible */ 163 int Socket_new(const char* addr, size_t addr_len, int port, SOCKET* socket, long timeout); 164 #else 165 int Socket_new(const char* addr, size_t addr_len, int port, SOCKET* socket); 166 #endif 167 168 int Socket_noPendingWrites(SOCKET socket); 169 char* Socket_getpeer(SOCKET sock); 170 171 void Socket_addPendingWrite(SOCKET socket); 172 void Socket_clearPendingWrite(SOCKET socket); 173 174 typedef void Socket_writeContinue(SOCKET socket); 175 void Socket_setWriteContinueCallback(Socket_writeContinue*); 176 177 typedef void Socket_writeComplete(SOCKET socket, int rc); 178 void Socket_setWriteCompleteCallback(Socket_writeComplete*); 179 180 typedef void Socket_writeAvailable(SOCKET socket); 181 void Socket_setWriteAvailableCallback(Socket_writeAvailable*); 182 183 #endif /* SOCKET_H */ 184