Josh Soref abce91d14b
Spelling (#12954)
* 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>
2025-07-23 15:19:00 -07:00

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);
}