Skip to content
This repository was archived by the owner on May 27, 2021. It is now read-only.

Fixed Windows client streams, C++ compilation and added fast loopback path for Windows #29

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 73 additions & 8 deletions src/dyad.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#endif
#include <winsock2.h>
#include <ws2tcpip.h>
#include <Mstcpip.h>
#include <windows.h>
#else
#define _POSIX_C_SOURCE 200809L
Expand Down Expand Up @@ -108,7 +109,7 @@ static void vec_expand(char **data, int *length, int *capacity, int memsz) {
} else {
*capacity <<= 1;
}
*data = dyad_realloc(*data, *capacity * memsz);
*data = (char*)dyad_realloc(*data, *capacity * memsz);
}
}

Expand Down Expand Up @@ -202,7 +203,7 @@ static void select_grow(SelectSet *s) {
int oldCapacity = s->capacity;
s->capacity = s->capacity ? s->capacity << 1 : 1;
for (i = 0; i < SELECT_MAX; i++) {
s->fds[i] = dyad_realloc(s->fds[i], s->capacity * sizeof(fd_set));
s->fds[i] = (fd_set*)dyad_realloc(s->fds[i], s->capacity * sizeof(fd_set));
memset(s->fds[i] + oldCapacity, 0,
(s->capacity - oldCapacity) * sizeof(fd_set));
}
Expand Down Expand Up @@ -286,6 +287,9 @@ struct dyad_Stream {
Vec(Listener) listeners;
Vec(char) lineBuffer;
Vec(char) writeBuffer;
#ifdef _WIN32
int win32FastLoopbackPathEnabled;
#endif
dyad_Stream *next;
};

Expand Down Expand Up @@ -459,12 +463,12 @@ static void stream_initAddress(dyad_Stream *stream) {
}
}
if (addr.sas.ss_family == AF_INET6) {
stream->address = dyad_realloc(NULL, INET6_ADDRSTRLEN);
stream->address = (char*)dyad_realloc(NULL, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, &addr.sai6.sin6_addr, stream->address,
INET6_ADDRSTRLEN);
stream->port = ntohs(addr.sai6.sin6_port);
} else {
stream->address = dyad_realloc(NULL, INET_ADDRSTRLEN);
stream->address = (char*)dyad_realloc(NULL, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &addr.sai.sin_addr, stream->address, INET_ADDRSTRLEN);
stream->port = ntohs(addr.sai.sin_port);
}
Expand All @@ -490,6 +494,39 @@ static void stream_setSocket(dyad_Stream *stream, dyad_Socket sockfd) {
}


#ifdef _WIN32
static int win32EnableFastLoopbackPath(dyad_Socket socket) {
int optionValue = 1;
DWORD numberOfBytesReturned = 0;

int status = WSAIoctl(
socket,
SIO_LOOPBACK_FAST_PATH,
&optionValue,
sizeof(optionValue),
NULL,
0,
&numberOfBytesReturned,
0,
0);

if (status == SOCKET_ERROR) {
DWORD lastError = ::GetLastError();

if (lastError = WSAEOPNOTSUPP) {
/* Not supported on current Windows version. */
return -2;
}
else {
return -1;

}
}
return 0;
}
#endif


static int stream_initSocket(
dyad_Stream *stream, int domain, int type, int protocol
) {
Expand All @@ -499,6 +536,12 @@ static int stream_initSocket(
return -1;
}
stream_setSocket(stream, stream->sockfd);
#ifdef _WIN32
if (stream->win32FastLoopbackPathEnabled) {
int status = win32EnableFastLoopbackPath(stream->sockfd);
return status;
}
#endif
return 0;
}

Expand Down Expand Up @@ -868,11 +911,14 @@ dyad_PanicCallback dyad_atPanic(dyad_PanicCallback func) {
/*---------------------------------------------------------------------------*/

dyad_Stream *dyad_newStream(void) {
dyad_Stream *stream = dyad_realloc(NULL, sizeof(*stream));
dyad_Stream *stream = (dyad_Stream*)dyad_realloc(NULL, sizeof(*stream));
memset(stream, 0, sizeof(*stream));
stream->state = DYAD_STATE_CLOSED;
stream->sockfd = INVALID_SOCKET;
stream->lastActivity = dyad_getTime();
#ifdef _WIN32
stream->win32FastLoopbackPathEnabled = 0;
#endif
/* Add to list and increment count */
stream->next = dyad_streams;
dyad_streams = stream;
Expand Down Expand Up @@ -958,7 +1004,11 @@ int dyad_listenEx(

/* Get addrinfo */
memset(&hints, 0, sizeof(hints));
#ifdef _WIN32
hints.ai_family = AF_INET;
#else
hints.ai_family = AF_UNSPEC;
#endif
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
sprintf(buf, "%d", port);
Expand Down Expand Up @@ -1014,7 +1064,11 @@ int dyad_connect(dyad_Stream *stream, const char *host, int port) {

/* Resolve host */
memset(&hints, 0, sizeof(hints));
#ifdef _WIN32
hints.ai_family = AF_INET;
#else
hints.ai_family = AF_UNSPEC;
#endif
hints.ai_socktype = SOCK_STREAM;
sprintf(buf, "%d", port);
err = getaddrinfo(host, buf, &hints, &ai);
Expand All @@ -1037,7 +1091,7 @@ int dyad_connect(dyad_Stream *stream, const char *host, int port) {


void dyad_write(dyad_Stream *stream, const void *data, int size) {
const char *p = data;
const char *p = (const char*)data;
while (size--) {
vec_push(&stream->writeBuffer, *p++);
}
Expand All @@ -1058,7 +1112,7 @@ void dyad_vwritef(dyad_Stream *stream, const char *fmt, va_list args) {
case 'r':
fp = va_arg(args, FILE*);
if (fp == NULL) {
str = "(null)";
str = (char*)"(null)";
goto writeStr;
}
while ((c = fgetc(fp)) != EOF) {
Expand All @@ -1070,7 +1124,7 @@ void dyad_vwritef(dyad_Stream *stream, const char *fmt, va_list args) {
break;
case 's':
str = va_arg(args, char*);
if (str == NULL) str = "(null)";
if (str == NULL) str = (char*)"(null)";
writeStr:
while (*str) {
vec_push(&stream->writeBuffer, *str++);
Expand Down Expand Up @@ -1154,3 +1208,14 @@ int dyad_getBytesReceived(dyad_Stream *stream) {
dyad_Socket dyad_getSocket(dyad_Stream *stream) {
return stream->sockfd;
}


int dyad_win32EnableFastLoopbackPath(dyad_Stream *stream) {
#ifdef _WIN32
/* TODO: check if the feature is supported to allow for early failure */
stream->win32FastLoopbackPathEnabled = 1;
return 0;
#else
return -1;
#endif
}
1 change: 1 addition & 0 deletions src/dyad.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ int dyad_getPort(dyad_Stream *stream);
int dyad_getBytesSent(dyad_Stream *stream);
int dyad_getBytesReceived(dyad_Stream *stream);
dyad_Socket dyad_getSocket(dyad_Stream *stream);
int dyad_win32EnableFastLoopbackPath(dyad_Stream *stream);

#ifdef __cplusplus
} // extern "C"
Expand Down