mirror of
https://github.com/microsoft/WSL.git
synced 2025-12-10 00:44:55 -06:00
* link: Collect WSL logs (recommended method) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Advanced Authoring Tests in C++ Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: CMake Documentation and Community Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Collect WSL logs for networking issues Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * link: Collect WSL logs (recommended method) Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: ; otherwise, Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: a Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: access Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: accessible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: across Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: actively Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: adapters Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: address Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: addresses Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: and Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: appropriate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: argument Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: associated Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: attach Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: available Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: beginning Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: between Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: binaries Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: bound Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: buffer Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: buffers Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: cannot Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: canonical Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: capabilities Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-insensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: case-sensitive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: certified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: command Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: committer Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: communication Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: complains Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: configuration Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: consumed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: continue Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: converted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: currently Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: customers Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: daemon Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: deferred Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: definitions Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: delimiter Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: delivered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: dellink Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: derived Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: descriptor Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destined Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destruct Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destructible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: destructor Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: detach Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: differentiate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: directories Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: disassociate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: disposition Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: distribution Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: distro Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: duping Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: emitted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: empty Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: environment Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: every time Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: exclusive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: expected Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: expire Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: explicitly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: fall back Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: false Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: fastfail Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: filesystem Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: first Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: followed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: for Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: functionality Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: functionally Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: github Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: greater Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: guarantee Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: guaranteed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: handles Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hangup Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hierarchy Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hogwarts Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: hydrated Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: icrnl Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: implementation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: implementing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: initialize Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instance Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instantiate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: instantiations Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: intentionally Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: interpret Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: interpreter Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: irreversibly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: iteration Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: iterator Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: its Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: kernel Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: kmsg Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: knowledge Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: maximum Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: mirrored Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: msftconnecttest Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: multi Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: multiple Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: mutable Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: namespace Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: nonexistent Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: notifications Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: occurred Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: occurring Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: otherwise, Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: outstanding Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: overridden Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: partition Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: pass through Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: passthrough Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: performs Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: periodically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: positional Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: precedence Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preexisting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: preferring Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: prepopulate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: previous Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: privileges Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: process Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: processes Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: programmatically Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: protection Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: provided Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: reasonable Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: receive Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: received Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: red hat Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: reentrant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: registered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: regularly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: relay Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: release Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: representing Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: requests Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: response Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: resurrect Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: retention Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: returned Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: security Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: semaphore Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: separator Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: service Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: set up Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: setup Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: severely Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: should Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: signal Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: similarly Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: simple Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: simplified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: single Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: specified Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: splitting Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: standard Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: stress Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: succeed Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: success Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: successfully Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: supplementary Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: synced Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: system Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: take Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: than Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: that opening Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: the Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: threadpool Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: to Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: true Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: truncate Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: tunneling Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unexpected Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: uninitialize Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unique Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unprivileged Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: unregistered Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: untrusted Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: upgrade Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: utility Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: validating Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variant Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variation Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: variations Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: verify Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: visible Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: whether Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: winget Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: worker Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: written Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * spelling: wslservice Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> * format source --------- Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> Co-authored-by: Ben Hillis <benhillis@gmail.com> Co-authored-by: Ben Hillis <benhill@ntdev.microsoft.com>
1112 lines
29 KiB
C
1112 lines
29 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
socket.c
|
|
|
|
Abstract:
|
|
|
|
Linux socket client / server test.
|
|
|
|
--*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
#include "lxtcommon.h"
|
|
#include "unittests.h"
|
|
#include "common.h"
|
|
|
|
#define LXT_NAME_CLIENT "SocketClient"
|
|
#define LXT_NAME_SERVER "SocketServer"
|
|
|
|
#define LXT_AF_UNIX_SOCKET_PATH "af_unix_socket"
|
|
|
|
#define FD_STDOUT 1
|
|
//
|
|
// Function declarations.
|
|
//
|
|
|
|
long long GetTickCount(void);
|
|
|
|
int SocketClientDgram(PLXT_ARGS Args);
|
|
|
|
int SocketClientSend(int NumConnectAndSends, int Family, int Type, int Protocol);
|
|
|
|
int SocketClientSendMultiple(PLXT_ARGS Args);
|
|
|
|
int SocketClientSendMultipleIpv6(PLXT_ARGS Args);
|
|
|
|
int SocketClientSendWithFlags(PLXT_ARGS Args);
|
|
|
|
int SocketClientUnix(PLXT_ARGS Args);
|
|
|
|
int SocketCreateAcceptedSockets(int Family, int Type, int Protocol);
|
|
|
|
int SocketCreateBoundSocket(int Family, int Type, int Protocol);
|
|
|
|
int SocketCreateConnectSocket(int Family, int Type, int Protocol);
|
|
|
|
int SocketGetSockName(PLXT_ARGS Args);
|
|
|
|
int SocketParseCommandLine(int Argc, char* Argv[], LXT_ARGS* Args);
|
|
|
|
int SocketServerAccept(int NumAccepts, int Family, int Type, int Protocol);
|
|
|
|
int SocketServerAcceptMultiple(PLXT_ARGS Args);
|
|
|
|
int SocketServerAcceptMultipleIpv6(PLXT_ARGS Args);
|
|
|
|
int SocketServerAcceptWithFlags(PLXT_ARGS Args);
|
|
|
|
int SocketServerDgram(PLXT_ARGS Args);
|
|
|
|
int SocketServerUnix(PLXT_ARGS Args);
|
|
|
|
//
|
|
// Global constants.
|
|
//
|
|
|
|
static const LXT_VARIATION g_LxtClientVariations[] = {
|
|
{"Socket Client - send multiple", SocketClientSendMultiple},
|
|
{"Socket Client - AF_UNIX", SocketClientUnix},
|
|
{"Socket Client - send multiple Ipv6", SocketClientSendMultipleIpv6},
|
|
{"Socket Client - send (MSG_WAITALL)", SocketClientSendWithFlags},
|
|
{"Socket Client - SOCK_DGRAM", SocketClientDgram},
|
|
|
|
//
|
|
// Variations that do not require a server.
|
|
//
|
|
|
|
{"Socket - getsockname", SocketGetSockName},
|
|
};
|
|
|
|
//
|
|
// N.B. Keep the number of variations up to date with
|
|
// LXT_SOCKET_NUM_SERVER_VARIATIONS in socket/common.h
|
|
//
|
|
|
|
static const LXT_VARIATION g_LxtServerVariations[] = {
|
|
{"Socket Server - accept multiple", SocketServerAcceptMultiple},
|
|
{"Socket Server - AF_UNIX", SocketServerUnix},
|
|
{"Socket Server - accept multiple Ipv6", SocketServerAcceptMultipleIpv6},
|
|
{"Socket Server - accept (MSG_WAITALL)", SocketServerAcceptWithFlags},
|
|
{"Socket Server - SOCK_DGRAM", SocketServerDgram}};
|
|
|
|
//
|
|
// Function definitions.
|
|
//
|
|
|
|
long long GetTickCount(void)
|
|
{
|
|
|
|
struct timespec Now;
|
|
|
|
if (clock_gettime(CLOCK_MONOTONIC, &Now))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return Now.tv_sec * 1000 + Now.tv_nsec / 1000000;
|
|
}
|
|
|
|
int main(int Argc, char* Argv[])
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
LXT_ARGS Args;
|
|
int Result;
|
|
|
|
LxtCheckResult(SocketParseCommandLine(Argc, Argv, &Args))
|
|
|
|
ErrorExit : LxtUninitialize();
|
|
return !LXT_SUCCESS(Result);
|
|
}
|
|
|
|
int SocketClientDgram(PLXT_ARGS Args)
|
|
{
|
|
|
|
char ReceiveBuffer[LXT_SOCKET_DEFAULT_BUFFER_LENGTH] = {0};
|
|
int Result = LXT_RESULT_FAILURE;
|
|
char* SendBuffer;
|
|
struct sockaddr* ServerAddress = {0};
|
|
struct sockaddr_in ServerAddressIpv4 = {0};
|
|
struct sockaddr_in6 ServerAddressIpv6 = {0};
|
|
struct sockaddr_un ServerAddressUnix = {0};
|
|
int ServerAddressLength;
|
|
int Size;
|
|
int Socket = 0;
|
|
|
|
sleep(2);
|
|
|
|
Socket = socket(AF_INET6, SOCK_DGRAM, 0);
|
|
if (Socket < 0)
|
|
{
|
|
LxtLogError("socket(AF_INET6, SOCK_DGRAM, 0) - %s", strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
ServerAddressIpv6.sin6_family = AF_INET6;
|
|
ServerAddressIpv6.sin6_addr = in6addr_loopback;
|
|
ServerAddressIpv6.sin6_port = htons(LXT_SOCKET_DEFAULT_PORT_IPV6);
|
|
ServerAddress = (struct sockaddr*)&ServerAddressIpv6;
|
|
ServerAddressLength = sizeof(ServerAddressIpv6);
|
|
SendBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
|
|
|
|
Size = sendto(Socket, SendBuffer, strlen(SendBuffer), 0, ServerAddress, ServerAddressLength);
|
|
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("sendto - %s", strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Size = recvfrom(Socket, ReceiveBuffer, sizeof(ReceiveBuffer), 0, ServerAddress, &ServerAddressLength);
|
|
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("recvfrom - %s", strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtLogInfo("Received from server: %s", ReceiveBuffer);
|
|
|
|
if (memcmp(SendBuffer, ReceiveBuffer, Size) != 0)
|
|
{
|
|
LxtLogError("Message received back from server %s did not match expected %s", ReceiveBuffer, SendBuffer);
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Socket > 0)
|
|
{
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SocketClientSend(int NumConnectAndSends, int Family, int Type, int Protocol)
|
|
|
|
{
|
|
|
|
int Index;
|
|
char ReceiveBuffer[LXT_SOCKET_DEFAULT_BUFFER_LENGTH] = {0};
|
|
int Result = LXT_RESULT_FAILURE;
|
|
char* SendBuffer;
|
|
int Size;
|
|
int Socket = 0;
|
|
|
|
//
|
|
// Sleep to allow the server process to be listening.
|
|
//
|
|
|
|
sleep(2);
|
|
SendBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
|
|
for (Index = 0; Index < NumConnectAndSends; Index++)
|
|
{
|
|
Socket = SocketCreateConnectSocket(Family, Type, Protocol);
|
|
if (Socket <= 0)
|
|
{
|
|
LxtLogError("SocketCreateConnectSocket failed");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Size = send(Socket, SendBuffer, strlen(SendBuffer), 0);
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("send(%d, SendBuffer, strlen(SendBuffer), 0) - %s", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
memset(ReceiveBuffer, 0, sizeof(ReceiveBuffer));
|
|
Size = read(Socket, ReceiveBuffer, Size);
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("read(%d, ReceiveBuffer, sizeof(ReceiveBuffer) - %s", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtLogInfo("Received from server: %s", ReceiveBuffer);
|
|
|
|
if (memcmp(SendBuffer, ReceiveBuffer, Size) != 0)
|
|
{
|
|
LxtLogError("Message received back from server %s did not match expected %s", ReceiveBuffer, SendBuffer);
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
|
|
Socket = 0;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Socket > 0)
|
|
{
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SocketClientSendMultiple(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
return SocketClientSend(LXT_SOCKET_SERVER_MAX_BACKLOG_NUM, AF_INET, SOCK_STREAM, 0);
|
|
}
|
|
|
|
int SocketClientSendMultipleIpv6(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
return SocketClientSend(LXT_SOCKET_SERVER_MAX_BACKLOG_NUM, AF_INET6, SOCK_STREAM, 0);
|
|
}
|
|
|
|
int SocketClientSendWithFlags(PLXT_ARGS Args)
|
|
{
|
|
int FullMessageSize;
|
|
char* ReceiveBuffer;
|
|
int Result = LXT_RESULT_FAILURE;
|
|
char* SendBuffer;
|
|
int Size;
|
|
int Socket = 0;
|
|
|
|
//
|
|
// Sleep to allow the server process to be listening.
|
|
//
|
|
|
|
sleep(2);
|
|
SendBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
|
|
FullMessageSize = 2 * strlen(SendBuffer);
|
|
ReceiveBuffer = malloc(FullMessageSize);
|
|
if (ReceiveBuffer == NULL)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Socket = SocketCreateConnectSocket(AF_INET, SOCK_STREAM, 0);
|
|
if (Socket <= 0)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Size = send(Socket, SendBuffer, strlen(SendBuffer), 0);
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("send(%d, SendBuffer, strlen(SendBuffer), 0) - %s", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Sleep long enough that the second send won't be concatenated by WSK to
|
|
// test MSW_WAITALL code path.
|
|
//
|
|
|
|
sleep(1);
|
|
Size = send(Socket, SendBuffer, strlen(SendBuffer), 0);
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("send(%d, SendBuffer, strlen(SendBuffer), 0) - %s", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
memset(ReceiveBuffer, 0, FullMessageSize);
|
|
Size = recv(Socket, ReceiveBuffer, FullMessageSize, MSG_WAITALL);
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("read(%d, ReceiveBuffer, %d, MSG_WAITALL - %s", Socket, FullMessageSize, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtLogInfo("Received from server: %s", ReceiveBuffer);
|
|
|
|
if (memcmp(SendBuffer, ReceiveBuffer, FullMessageSize / 2) != 0)
|
|
{
|
|
LxtLogError("Message received back from server %s did not match expected %s", ReceiveBuffer, SendBuffer);
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (memcmp(SendBuffer, ReceiveBuffer + FullMessageSize / 2, sizeof(SendBuffer)) != 0)
|
|
{
|
|
|
|
LxtLogError("Message received back from server %s did not match expected %s", ReceiveBuffer, SendBuffer);
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Socket > 0)
|
|
{
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
}
|
|
|
|
if (ReceiveBuffer != NULL)
|
|
{
|
|
free(ReceiveBuffer);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SocketClientUnix(PLXT_ARGS Args)
|
|
{
|
|
|
|
return SocketClientSend(1, AF_UNIX, SOCK_SEQPACKET, 0);
|
|
}
|
|
|
|
int SocketCreateAcceptedSocket(int Socket, int Family)
|
|
{
|
|
|
|
int AcceptedSocket = 0;
|
|
int Result = LXT_RESULT_FAILURE;
|
|
struct sockaddr* Address;
|
|
struct sockaddr_in AddressIpv4 = {0};
|
|
struct sockaddr_in6 AddressIpv6 = {0};
|
|
struct sockaddr_un AddressUnix = {0};
|
|
socklen_t AddressLength;
|
|
|
|
switch (Family)
|
|
{
|
|
case AF_INET:
|
|
Address = (struct sockaddr*)&AddressIpv4;
|
|
AddressLength = sizeof(AddressIpv4);
|
|
break;
|
|
|
|
case AF_INET6:
|
|
Address = (struct sockaddr*)&AddressIpv6;
|
|
AddressLength = sizeof(AddressIpv6);
|
|
break;
|
|
|
|
case AF_UNIX:
|
|
Address = (struct sockaddr*)&AddressUnix;
|
|
AddressLength = sizeof(AddressUnix);
|
|
break;
|
|
|
|
default:
|
|
LxtLogError("Unsupported Family %d", Family);
|
|
AcceptedSocket = 0;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
AcceptedSocket = accept(Socket, Address, &AddressLength);
|
|
|
|
if (AcceptedSocket < 0)
|
|
{
|
|
LxtLogError("accept(%d, Address, &AddressLength) - %s", Socket, strerror(errno));
|
|
|
|
close(AcceptedSocket);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = AcceptedSocket;
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int SocketCreateBoundSocket(int Family, int Type, int Protocol)
|
|
{
|
|
int OptVal;
|
|
int Result = LXT_RESULT_FAILURE;
|
|
struct sockaddr* ServerAddress;
|
|
int ServerAddressSize;
|
|
struct sockaddr_in ServerAddressIpv4 = {0};
|
|
struct sockaddr_in6 ServerAddressIpv6 = {0};
|
|
struct sockaddr_un ServerAddressUnix = {0};
|
|
int Size;
|
|
int Socket = 0;
|
|
|
|
Socket = socket(Family, Type, Protocol);
|
|
if (Socket < 0)
|
|
{
|
|
LxtLogError("socket(%d, %d, %d) - %s", Family, Type, Protocol, strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// TODO: when setsockopt is implemented uncomment the below.
|
|
//
|
|
// OptVal = 1;
|
|
// if (setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, &OptVal, sizeof(OptVal)) < 0) {
|
|
// LxtLogError("setsockopt(%d, SOL_SOCKET, SO_REUSEADDR, &OptVal, sizeof(OptVal)) - %s",
|
|
// Socket,
|
|
// strerror(errno));
|
|
// goto ErrorExit;
|
|
//}
|
|
|
|
switch (Family)
|
|
{
|
|
case AF_INET:
|
|
ServerAddressIpv4.sin_family = AF_INET;
|
|
ServerAddressIpv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
ServerAddressIpv4.sin_port = htons(LXT_SOCKET_DEFAULT_PORT);
|
|
ServerAddress = (struct sockaddr*)&ServerAddressIpv4;
|
|
ServerAddressSize = sizeof(ServerAddressIpv4);
|
|
break;
|
|
|
|
case AF_INET6:
|
|
ServerAddressIpv6.sin6_family = AF_INET6;
|
|
ServerAddressIpv6.sin6_addr = in6addr_loopback;
|
|
ServerAddressIpv6.sin6_port = htons(LXT_SOCKET_DEFAULT_PORT_IPV6);
|
|
ServerAddress = (struct sockaddr*)&ServerAddressIpv6;
|
|
ServerAddressSize = sizeof(ServerAddressIpv6);
|
|
break;
|
|
|
|
case AF_UNIX:
|
|
ServerAddressUnix.sun_family = AF_UNIX;
|
|
strcpy(ServerAddressUnix.sun_path, LXT_AF_UNIX_SOCKET_PATH);
|
|
ServerAddress = (struct sockaddr*)&ServerAddressUnix;
|
|
ServerAddressSize = sizeof(ServerAddressUnix);
|
|
// unlink(LXT_AF_UNIX_SOCKET_PATH); // TODO: when unlink is implemented uncomment this.
|
|
break;
|
|
|
|
default:
|
|
LxtLogError("Unsupported Family %d", Family);
|
|
close(Socket);
|
|
Socket = 0;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (bind(Socket, ServerAddress, ServerAddressSize) < 0)
|
|
{
|
|
LxtLogError("bind(%d, ServerAddress, ServerAddressSize) - %s", Socket, strerror(errno));
|
|
|
|
close(Socket);
|
|
Socket = 0;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = Socket;
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int SocketCreateConnectSocket(int Family, int Type, int Protocol)
|
|
{
|
|
|
|
int Result = LXT_RESULT_FAILURE;
|
|
struct sockaddr* ServerAddress = NULL;
|
|
struct sockaddr_in ServerAddressIpv4 = {0};
|
|
struct sockaddr_in6 ServerAddressIpv6 = {0};
|
|
int ServerAddressSize;
|
|
struct sockaddr_un ServerAddressUnix = {0};
|
|
int Size;
|
|
int Socket = 0;
|
|
|
|
Socket = socket(Family, Type, Protocol);
|
|
if (Socket < 0)
|
|
{
|
|
LxtLogError("socket(%d, %d, %d) - %s", Family, Type, Protocol, strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
switch (Family)
|
|
{
|
|
case AF_INET:
|
|
ServerAddressIpv4.sin_family = AF_INET;
|
|
ServerAddressIpv4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
ServerAddressIpv4.sin_port = htons(LXT_SOCKET_DEFAULT_PORT);
|
|
ServerAddress = (struct sockaddr*)&ServerAddressIpv4;
|
|
ServerAddressSize = sizeof(ServerAddressIpv4);
|
|
break;
|
|
|
|
case AF_INET6:
|
|
ServerAddressIpv6.sin6_family = AF_INET6;
|
|
ServerAddressIpv6.sin6_addr = in6addr_loopback;
|
|
ServerAddressIpv6.sin6_port = htons(LXT_SOCKET_DEFAULT_PORT_IPV6);
|
|
ServerAddress = (struct sockaddr*)&ServerAddressIpv6;
|
|
ServerAddressSize = sizeof(ServerAddressIpv6);
|
|
break;
|
|
|
|
case AF_UNIX:
|
|
ServerAddressUnix.sun_family = AF_UNIX;
|
|
strcpy(ServerAddressUnix.sun_path, LXT_AF_UNIX_SOCKET_PATH);
|
|
ServerAddress = (struct sockaddr*)&ServerAddressUnix;
|
|
ServerAddressSize = sizeof(ServerAddressUnix);
|
|
break;
|
|
|
|
default:
|
|
LxtLogError("LxtSocketClientSend Unsupported Family %d", Family);
|
|
close(Socket);
|
|
Socket = 0;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (connect(Socket, ServerAddress, ServerAddressSize) < 0)
|
|
{
|
|
LxtLogError("connect failed - %s", strerror(errno));
|
|
close(Socket);
|
|
Socket = 0;
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = Socket;
|
|
|
|
ErrorExit:
|
|
return Result;
|
|
}
|
|
|
|
int SocketGetSockName(PLXT_ARGS Args)
|
|
{
|
|
union
|
|
{
|
|
struct in_addr Addr;
|
|
struct in6_addr AddrIpv6;
|
|
} Addr;
|
|
struct sockaddr_storage Address = {0};
|
|
int AddressFamilies[] = {AF_INET, AF_INET6};
|
|
int AddressFamily;
|
|
int AddressSize;
|
|
int Port;
|
|
int Result = LXT_RESULT_FAILURE;
|
|
int Socket = 0;
|
|
int Index;
|
|
|
|
for (Index = 0; Index < (int)LXT_COUNT_OF(AddressFamilies); Index++)
|
|
{
|
|
Socket = socket(AddressFamilies[Index], SOCK_STREAM, 0);
|
|
if (Socket < 0)
|
|
{
|
|
LxtLogError("socket(%d, SOCK_STREAM, 0) - %s", AddressFamilies[Index], strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
switch (AddressFamilies[Index])
|
|
{
|
|
case AF_INET:
|
|
((struct sockaddr_in*)&Address)->sin_family = AF_INET;
|
|
((struct sockaddr_in*)&Address)->sin_port = htons(0);
|
|
((struct sockaddr_in*)&Address)->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
|
AddressSize = sizeof(struct sockaddr_in);
|
|
break;
|
|
|
|
case AF_INET6:
|
|
((struct sockaddr_in6*)&Address)->sin6_family = AF_INET6;
|
|
((struct sockaddr_in6*)&Address)->sin6_port = htons(0);
|
|
((struct sockaddr_in6*)&Address)->sin6_addr = in6addr_loopback;
|
|
AddressSize = sizeof(struct sockaddr_in6);
|
|
break;
|
|
|
|
default:
|
|
LxtLogError("Unsupported Family %d", AddressFamilies[Index]);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (bind(Socket, (struct sockaddr*)&Address, AddressSize) < 0)
|
|
{
|
|
LxtLogError("bind(%d, (struct sockaddr*)&Address, AddressSize) - %s", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (getsockname(Socket, (struct sockaddr*)&Address, &AddressSize) < 0)
|
|
{
|
|
LxtLogError("getsockname(%d, &Address, &AddressSize) - %s", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
memset(&Addr, 0, sizeof(Addr));
|
|
switch (AddressFamilies[Index])
|
|
{
|
|
case AF_INET:
|
|
AddressFamily = ((struct sockaddr_in*)&Address)->sin_family;
|
|
Port = ((struct sockaddr_in*)&Address)->sin_port;
|
|
memcpy(
|
|
(struct sockaddr_in*)&Addr,
|
|
&((struct sockaddr_in*)&Address)->sin_addr.s_addr,
|
|
sizeof(((struct sockaddr_in*)&Address)->sin_addr.s_addr));
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
AddressFamily = ((struct sockaddr_in6*)&Address)->sin6_family;
|
|
Port = ((struct sockaddr_in6*)&Address)->sin6_port;
|
|
memcpy(
|
|
(struct sockaddr_in6*)&Addr, &((struct sockaddr_in6*)&Address)->sin6_addr, sizeof(((struct sockaddr_in6*)&Address)->sin6_addr));
|
|
|
|
break;
|
|
|
|
default:
|
|
LxtLogError("Unsupported AddressFamily %d", AddressFamilies[Index]);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (AddressFamily != AddressFamilies[Index])
|
|
{
|
|
LxtLogError("Socket %d is bound, address family %d should be %d", Socket, AddressFamily, AddressFamilies[Index], strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (Port == 0)
|
|
{
|
|
LxtLogError("Socket %d is bound, port should be non-null", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Create the underlaying socket and query again, port should be the same.
|
|
//
|
|
|
|
if (listen(Socket, 32) < 0)
|
|
{
|
|
LxtLogError("listen(%d, 32) - %s", Socket, strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (getsockname(Socket, (struct sockaddr*)&Address, &AddressSize) < 0)
|
|
{
|
|
LxtLogError("getsockname(%d, &Address, &AddressSize) - %s", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
switch (AddressFamilies[Index])
|
|
{
|
|
case AF_INET:
|
|
if (AddressFamily != ((struct sockaddr_in*)&Address)->sin_family)
|
|
{
|
|
LxtLogError("Socket %d is bound, address family %d should be %d", Socket, ((struct sockaddr_in*)&Address)->sin_family, AddressFamily, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (Port != ((struct sockaddr_in*)&Address)->sin_port)
|
|
{
|
|
LxtLogError("Socket %d should be bound to port %d", Socket, Port, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (memcmp(&Addr, &((struct sockaddr_in*)&Address)->sin_addr.s_addr, sizeof(((struct sockaddr_in*)&Address)->sin_addr.s_addr)) != 0)
|
|
{
|
|
|
|
LxtLogError("Socket %d addr should be localhost", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
break;
|
|
|
|
case AF_INET6:
|
|
if (AddressFamily != ((struct sockaddr_in6*)&Address)->sin6_family)
|
|
{
|
|
LxtLogError(
|
|
"Socket %d is bound, address family %d should be %d",
|
|
Socket,
|
|
((struct sockaddr_in6*)&Address)->sin6_family,
|
|
AddressFamily,
|
|
strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (Port != ((struct sockaddr_in6*)&Address)->sin6_port)
|
|
{
|
|
LxtLogError("Socket %d should be bound to port %d", Socket, Port, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (memcmp(&Addr, &((struct sockaddr_in6*)&Address)->sin6_addr, sizeof(((struct sockaddr_in6*)&Address)->sin6_addr)) != 0)
|
|
{
|
|
|
|
LxtLogError("Socket %d addr should be localhost", Socket, strerror(errno));
|
|
|
|
goto ErrorExit;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
LxtLogError("Unsupported Family %d", AddressFamilies[Index]);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
|
|
Socket = 0;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Socket > 0)
|
|
{
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SocketParseCommandLine(int Argc, char* Argv[], LXT_ARGS* Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
int ArgvIndex;
|
|
int Result;
|
|
int ValidArguments;
|
|
|
|
Result = LXT_RESULT_FAILURE;
|
|
ValidArguments = 0;
|
|
|
|
if (Argc < 2)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
for (ArgvIndex = 1; ArgvIndex < Argc; ++ArgvIndex)
|
|
{
|
|
if (Argv[ArgvIndex][0] != '-')
|
|
{
|
|
printf("Unexpected character %s\n", Argv[ArgvIndex]);
|
|
goto ErrorExit;
|
|
}
|
|
|
|
switch (Argv[ArgvIndex][1])
|
|
{
|
|
case 'c':
|
|
|
|
//
|
|
// Run client variations.
|
|
//
|
|
|
|
ValidArguments = 1;
|
|
LxtCheckResult(LxtInitialize(Argc, Argv, Args, LXT_NAME_CLIENT));
|
|
LxtCheckResult(LxtRunVariations(Args, g_LxtClientVariations, LXT_COUNT_OF(g_LxtClientVariations)));
|
|
break;
|
|
|
|
case 's':
|
|
|
|
//
|
|
// Run server variations.
|
|
//
|
|
|
|
ValidArguments = 1;
|
|
LxtCheckResult(LxtInitialize(Argc, Argv, Args, LXT_NAME_SERVER));
|
|
LxtCheckResult(LxtRunVariations(Args, g_LxtServerVariations, LXT_COUNT_OF(g_LxtServerVariations)));
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
//
|
|
// This was already taken care of by LxtInitialize.
|
|
//
|
|
|
|
++ArgvIndex;
|
|
|
|
break;
|
|
|
|
default:
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
ErrorExit:
|
|
if (ValidArguments == 0)
|
|
{
|
|
printf("\nuse: socket <One of the below arguments>\n");
|
|
printf("\t-c : Run all client variations (server must already be running)\n");
|
|
printf("\t-s : Run all server variations\n");
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SocketServerDgram(PLXT_ARGS Args)
|
|
{
|
|
|
|
char Buffer[LXT_SOCKET_DEFAULT_BUFFER_LENGTH] = {0};
|
|
struct sockaddr* FromAddress = {0};
|
|
struct sockaddr_in FromAddressIpv4 = {0};
|
|
struct sockaddr_in6 FromAddressIpv6 = {0};
|
|
struct sockaddr_un FromAddressUnix = {0};
|
|
int FromAddressLength;
|
|
int Result = LXT_RESULT_FAILURE;
|
|
int Size;
|
|
int Socket = 0;
|
|
|
|
Socket = SocketCreateBoundSocket(AF_INET6, SOCK_DGRAM, 0);
|
|
if (Socket < 0)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
FromAddress = (struct sockaddr*)&FromAddressIpv6;
|
|
FromAddressLength = sizeof(FromAddressIpv6);
|
|
|
|
Size = recvfrom(Socket, Buffer, sizeof(Buffer), 0, FromAddress, &FromAddressLength);
|
|
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("recvfrom - %s", strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtLogInfo("Received : %s", Buffer);
|
|
|
|
Size = sendto(Socket, Buffer, Size, 0, FromAddress, FromAddressLength);
|
|
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("sendto - %s", strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Socket > 0)
|
|
{
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SocketServerAccept(int NumAccepts, int Family, int Type, int Protocol)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
char Buffer[LXT_SOCKET_DEFAULT_BUFFER_LENGTH] = {0};
|
|
int ClientSockets[LXT_SOCKET_SERVER_MAX_BACKLOG_NUM] = {0};
|
|
int Index;
|
|
int Result = LXT_RESULT_FAILURE;
|
|
int Size;
|
|
int Socket = 0;
|
|
|
|
Socket = SocketCreateBoundSocket(Family, Type, Protocol);
|
|
if (Socket < 0)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (listen(Socket, NumAccepts) < 0)
|
|
{
|
|
LxtLogError("listen(%d, %d) - %s", Socket, NumAccepts, strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
for (Index = 0; Index < NumAccepts; Index++)
|
|
{
|
|
ClientSockets[Index] = SocketCreateAcceptedSocket(Socket, Family);
|
|
if (ClientSockets[Index] < 0)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
memset(Buffer, 0, sizeof(Buffer));
|
|
Size = read(ClientSockets[Index], Buffer, sizeof(Buffer));
|
|
|
|
//
|
|
// TODO: might need to handle the case where the socket gets shut down
|
|
// without receiving any data as in the connect / close variation.
|
|
//
|
|
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("read(%d, Buffer, sizeof(Buffer)) - %s", ClientSockets[Index], strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtLogInfo("Received: %s", Buffer);
|
|
|
|
if (write(ClientSockets[Index], Buffer, Size) < 0)
|
|
{
|
|
LxtLogError("write(%d, Buffer, Size) - %s", ClientSockets[Index], strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
for (Index = 0; Index < NumAccepts; Index++)
|
|
{
|
|
if (ClientSockets[Index] > 0)
|
|
{
|
|
if (close(ClientSockets[Index]) < 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", ClientSockets[Index], strerror(errno));
|
|
}
|
|
}
|
|
}
|
|
|
|
if (Socket > 0)
|
|
{
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SocketServerAcceptMultiple(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
return SocketServerAccept(LXT_SOCKET_SERVER_MAX_BACKLOG_NUM, AF_INET, SOCK_STREAM, 0);
|
|
}
|
|
|
|
int SocketServerAcceptMultipleIpv6(PLXT_ARGS Args)
|
|
|
|
/*++
|
|
--*/
|
|
|
|
{
|
|
|
|
return SocketServerAccept(LXT_SOCKET_SERVER_MAX_BACKLOG_NUM, AF_INET6, SOCK_STREAM, 0);
|
|
}
|
|
|
|
int SocketServerAcceptWithFlags(PLXT_ARGS Args)
|
|
{
|
|
int AcceptedSocket = 0;
|
|
int Index;
|
|
char* ReceiveBuffer;
|
|
int Result = LXT_RESULT_FAILURE;
|
|
int Size;
|
|
int FullMessageSize;
|
|
int Socket = 0;
|
|
|
|
ReceiveBuffer = LXT_SOCKET_DEFAULT_SEND_STRING;
|
|
FullMessageSize = 2 * strlen(ReceiveBuffer);
|
|
ReceiveBuffer = malloc(FullMessageSize);
|
|
if (ReceiveBuffer == NULL)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Socket = SocketCreateBoundSocket(AF_INET, SOCK_STREAM, 0);
|
|
if (Socket < 0)
|
|
{
|
|
goto ErrorExit;
|
|
}
|
|
|
|
if (listen(Socket, 32) < 0)
|
|
{
|
|
LxtLogError("listen(%d, 32) - %s", Socket, strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
AcceptedSocket = SocketCreateAcceptedSocket(Socket, AF_INET);
|
|
memset(ReceiveBuffer, 0, sizeof(ReceiveBuffer));
|
|
Size = recv(AcceptedSocket, ReceiveBuffer, FullMessageSize, MSG_WAITALL);
|
|
|
|
//
|
|
// TODO: might need to handle the case where the socket gets shut down
|
|
// without receiving any data as in the connect / close variation.
|
|
//
|
|
|
|
if (Size < 0)
|
|
{
|
|
LxtLogError("recv(%d, Buffer, %d, MSG_WAITALL) - %s", AcceptedSocket, FullMessageSize, strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtLogInfo("Received: %s", ReceiveBuffer);
|
|
|
|
if (write(AcceptedSocket, ReceiveBuffer, Size) < 0)
|
|
{
|
|
LxtLogError("write(%d, Buffer, Size) - %s", AcceptedSocket, strerror(errno));
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (AcceptedSocket > 0)
|
|
{
|
|
if (close(AcceptedSocket) < 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", AcceptedSocket, strerror(errno));
|
|
}
|
|
}
|
|
|
|
if (Socket > 0)
|
|
{
|
|
if (close(Socket) != 0)
|
|
{
|
|
LxtLogError("close(%d) - %s", Socket, strerror(errno));
|
|
}
|
|
}
|
|
|
|
if (ReceiveBuffer != NULL)
|
|
{
|
|
free(ReceiveBuffer);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int SocketServerUnix(PLXT_ARGS Args)
|
|
{
|
|
|
|
return SocketServerAccept(1, AF_UNIX, SOCK_SEQPACKET, 0);
|
|
} |