/*++ Copyright (c) Microsoft. All rights reserved. Module Name: common.h Abstract: Common socket definitions and helper routines. --*/ #ifndef _LXT_SOCKET_COMMON_ #define _LXT_SOCKET_COMMON_ #define LXT_SOCKET_CLIENT_VARIATION_SLEEP_SECONDS 5 #define LXT_SOCKET_DEFAULT_BUFFER_LENGTH 512 #define LXT_SOCKET_DEFAULT_PORT 50001 #define LXT_SOCKET_DEFAULT_PORT_IPV6 50002 #define LXT_SOCKET_DEFAULT_PORT_STRING "50001" #define LXT_SOCKET_DEFAULT_PORT_IPV6_STRING "50002" #define LXT_SOCKET_VARIATION_TIMEOUT (5 * 1000) #define LXT_SOCKET_DEFAULT_BACKLOG 32 #define LXT_SOCKET_STREAM_STRING "SOCK_STREAM" #define LXT_SOCKET_DGRAM_STRING "SOCK_DGRAM" #define LXT_SOCKET_RAW_STRING "SOCK_RAW" #define LXT_SOCKET_SEQPACKET_STRING "SOCK_SEQPACKET" #define LXT_SOCKET_PACKET_STRING "SOCK_PACKET" #define LXT_SOCKET_AF_INET_STRING "AF_INET" #define LXT_SOCKET_AF_INET6_STRING "AF_INET6" #define LxtCheckBytesSendRecv(_requested, _actual) \ { \ if ((_requested) != (_actual)) \ { \ LxtLogError( \ "Bytes requested in send/recv do not match actual. " \ "Requested: %d, Actual:%d.", \ (_requested), \ (_actual)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ } #define LxtCheckPoll(_numfdsExpected, _numfdsActual, _reventExpected, _reventActual) \ { \ if ((_numfdsExpected) != (_numfdsActual)) \ { \ LxtLogError("poll returned unexpected value, expecting %d, actual: %d. revents: 0x%x", (_numfdsExpected), (_numfdsActual), (_reventActual)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ \ if ((_reventExpected) != (_reventActual)) \ { \ LxtLogError( \ "expected epoll events do not match actual. " \ "Expected: 0x%x, Actual: 0x%x", \ (_reventExpected), \ (_reventActual)); \ Result = LXT_RESULT_FAILURE; \ goto ErrorExit; \ } \ } // // This macro will send data from a socket to its connected peer. // #define LxtCheckSend(_clientsocket, _sendbuffer, _numbytes, _clientname) \ { \ LxtLogInfo("[%s]Sending data to server", (_clientname)); \ LxtCheckErrno((BytesSent = send((_clientsocket), (_sendbuffer), _numbytes, 0))); \ LxtCheckBytesSendRecv((ssize_t)_numbytes, BytesSent); \ } #define LxtCheckRecv(_servername, _clientname, _recvbuffer, _sendbuffer, _serversocket) \ { \ ExpectedBytes = strlen(_sendbuffer); \ LxtCheckErrno((BytesReceived = recvfrom((_serversocket), (_recvbuffer), sizeof(_recvbuffer), 0, NULL, NULL))); \ LxtCheckBytesSendRecv(ExpectedBytes, BytesReceived); \ LxtLogInfo("[%s]Data received from %s", (_servername), (_clientname)); \ } // // TODO: switch over to an array of strings to send / receive. // #define LXT_SOCKET_DEFAULT_SEND_STRING "test socket test string\n" #define LXT_SOCKET_SERVER_MAX_BACKLOG_NUM 5 #define LxtCheckEpoll(_fd, _event, _timeout) \ { \ LxtCheckErrno(LxtSocketEpoll((_fd), (_event), (_timeout))); \ } #define LxtCheckAncillaryCredentials(_cmsg, _pid, _uid, _gid) \ { \ struct ucred* Credentials; \ LxtCheckEqual((_cmsg)->cmsg_level, SOL_SOCKET, "%d"); \ LxtCheckEqual((_cmsg)->cmsg_type, SCM_CREDENTIALS, "%d"); \ LxtCheckEqual((_cmsg)->cmsg_len, CMSG_LEN(sizeof(struct ucred)), "%d"); \ Credentials = (struct ucred*)CMSG_DATA(_cmsg); \ LxtCheckEqual(Credentials->pid, (_pid), "%d"); \ LxtCheckEqual(Credentials->uid, (_uid), "%d"); \ LxtCheckEqual(Credentials->gid, (_gid), "%d"); \ } #define LxtSocketGetDomainAsString(_domain) (((_domain) == AF_INET) ? LXT_SOCKET_AF_INET_STRING : LXT_SOCKET_AF_INET6_STRING) // // Private macro to get the next message header which returns the first // control message when the control message pointer is NULL. glibc's // 'CMSG_NXTHDR' does not handle that case. // #define MY_CMSG_NXTHDR(_msghdr, _pcmsg) (((_pcmsg) == NULL) ? CMSG_FIRSTHDR(_msghdr) : CMSG_NXTHDR(_msghdr, _pcmsg)) int LxtSocketEpoll(int Descriptor, int Event, int Timeout); void* SocketBlockedReaderThread(void* Arg); void* SocketBlockedReaderZeroBufferThread(void* Arg); void* SocketBlockedWriterThread(void* Arg); struct cmsghdr* SocketGetControlMessage(struct msghdr* MessageHeader, struct cmsghdr* StartControlMessage, int Level, int Type); int SocketGetSetBooleanSocketOption(int Socket, int OptionLevel, int OptionName, bool SmallerSizeAllowed); char* SocketGetTypeAsString(int Type); int SocketStreamClientMsgWaitAll(int ConnectedSocket); int SocketStreamServerMsgWaitAll(int AcceptedSocket); #endif // _LXT_SOCKET_COMMON_