mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-26 07:25:25 +02:00
2-28 C1
This commit is contained in:
parent
3e61818f19
commit
4b6bb2ac18
@ -538,9 +538,9 @@ int pipelinetest()
|
|||||||
|
|
||||||
int __cdecl main(void)
|
int __cdecl main(void)
|
||||||
{
|
{
|
||||||
//return regular();
|
return regular();
|
||||||
//return async();
|
//return async();
|
||||||
writemode = TRUE;
|
writemode = TRUE;
|
||||||
//return throughput();
|
//return throughput();
|
||||||
return pipetest();
|
//return pipetest();
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,70 @@ extern "C" {
|
|||||||
|
|
||||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
|
||||||
#define DEFAULT_PORT "27015"
|
#define PORT "34912" // the port users will be connecting to
|
||||||
|
|
||||||
|
#define BACKLOG 10 // how many pending connections queue will hold
|
||||||
|
|
||||||
|
// get sockaddr, IPv4 or IPv6:
|
||||||
|
void *get_in_addr(struct sockaddr *sa)
|
||||||
|
{
|
||||||
|
if (sa->sa_family == AF_INET) {
|
||||||
|
return &(((struct sockaddr_in*)sa)->sin_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return &(((struct sockaddr_in6*)sa)->sin6_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
unset_nonblock(int fd)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
|
||||||
|
val = fcntl(fd, F_GETFL, 0);
|
||||||
|
if (val < 0) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (!(val & O_NONBLOCK)) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
val &= ~O_NONBLOCK;
|
||||||
|
if (fcntl(fd, F_SETFL, val) == -1) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
set_nonblock(int fd)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
|
||||||
|
val = fcntl(fd, F_GETFL, 0);
|
||||||
|
if (val < 0) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (val & O_NONBLOCK) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
val |= O_NONBLOCK;
|
||||||
|
if (fcntl(fd, F_SETFL, val) == -1) {
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int listen_fd = -1;
|
||||||
|
int accept_fd = -1;
|
||||||
|
int connect_fd = -1;
|
||||||
|
|
||||||
|
DWORD WINAPI MyThreadFunction(LPVOID lpParam)
|
||||||
|
{
|
||||||
|
accept_fd = accept(listen_fd, NULL, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace UnitTests
|
namespace UnitTests
|
||||||
{
|
{
|
||||||
@ -14,63 +77,139 @@ namespace UnitTests
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct addrinfo *result = NULL;
|
struct addrinfo *servinfo = NULL, *p;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
int ListenSocket = -1;
|
|
||||||
|
|
||||||
|
|
||||||
TEST_METHOD_INITIALIZE(TestMethodInitialize)
|
TEST_METHOD_INITIALIZE(TestMethodInitialize)
|
||||||
{
|
{
|
||||||
int iResult;
|
|
||||||
|
|
||||||
w32posix_initialize();
|
w32posix_initialize();
|
||||||
ZeroMemory(&hints, sizeof(hints));
|
listen_fd = -1;
|
||||||
hints.ai_family = AF_INET;
|
accept_fd = -1;
|
||||||
|
connect_fd = -1;
|
||||||
|
struct sockaddr_storage their_addr; // connector's address information
|
||||||
|
socklen_t sin_size;
|
||||||
|
int yes = 1;
|
||||||
|
char s[INET6_ADDRSTRLEN];
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof hints);
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
hints.ai_protocol = IPPROTO_TCP;
|
hints.ai_flags = AI_PASSIVE; // use my IP
|
||||||
hints.ai_flags = AI_PASSIVE;
|
|
||||||
|
|
||||||
iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
|
if ((rv = getaddrinfo("127.0.0.1", PORT, &hints, &servinfo)) != 0) {
|
||||||
if (iResult != 0) {
|
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
||||||
printf("getaddrinfo failed with error: %d\n", iResult);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
|
// loop through all the results and bind to the first we can
|
||||||
if (ListenSocket == -1) {
|
for (p = servinfo; p != NULL; p = p->ai_next) {
|
||||||
printf("socket failed with error: %ld\n", errno);
|
if ((listen_fd = socket(p->ai_family, p->ai_socktype,
|
||||||
return;
|
p->ai_protocol)) == -1) {
|
||||||
|
perror("server: socket");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes,
|
||||||
|
sizeof(int)) == -1) {
|
||||||
|
perror("setsockopt");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(listen_fd, p->ai_addr, p->ai_addrlen) == -1) {
|
||||||
|
int i = errno;
|
||||||
|
close(listen_fd);
|
||||||
|
perror("server: bind");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the TCP listening socket
|
freeaddrinfo(servinfo); // all done with this structure
|
||||||
iResult = bind(ListenSocket, result->ai_addr, (int)result->ai_addrlen);
|
servinfo = NULL;
|
||||||
if (iResult == -1) {
|
|
||||||
printf("bind failed with error: %d\n", errno);
|
if (p == NULL) {
|
||||||
return ;
|
fprintf(stderr, "server: failed to bind\n");
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
iResult = listen(ListenSocket, SOMAXCONN);
|
if (listen(listen_fd, BACKLOG) == -1) {
|
||||||
if (iResult == -1) {
|
perror("listen");
|
||||||
printf("listen failed with error: %d\n", errno);
|
exit(1);
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
freeaddrinfo(result);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD_CLEANUP(TestMethodCleanup)
|
TEST_METHOD_CLEANUP(TestMethodCleanup)
|
||||||
{
|
{
|
||||||
if (result)
|
if (servinfo)
|
||||||
freeaddrinfo(result);
|
freeaddrinfo(servinfo);
|
||||||
if (ListenSocket != -1)
|
if (listen_fd != -1)
|
||||||
close(ListenSocket);
|
close(listen_fd);
|
||||||
|
if (connect_fd != -1)
|
||||||
|
close(connect_fd);
|
||||||
|
if (accept_fd != -1)
|
||||||
|
close(accept_fd);
|
||||||
w32posix_done();
|
w32posix_done();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(TestMethod1)
|
TEST_METHOD(TestMethod1)
|
||||||
{
|
{
|
||||||
// TODO: Your test code here
|
int rv;
|
||||||
|
struct sockaddr_storage their_addr;
|
||||||
|
socklen_t sin_size;
|
||||||
|
int ret;
|
||||||
|
servinfo = NULL;
|
||||||
|
|
||||||
|
memset(&hints, 0, sizeof hints);
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
|
rv = getaddrinfo("::1", PORT, &hints, &servinfo);
|
||||||
|
Assert::AreEqual(rv, 0, L"getaddreinfo failed", LINE_INFO());
|
||||||
|
|
||||||
|
p = servinfo;
|
||||||
|
connect_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
|
||||||
|
Assert::AreNotEqual(connect_fd, -1, L"connect_fd", LINE_INFO());
|
||||||
|
|
||||||
|
//set_nonblock(listen_fd);
|
||||||
|
//set_nonblock(connect_fd);
|
||||||
|
|
||||||
|
//fd_set read_set;
|
||||||
|
//fd_set write_set;
|
||||||
|
//FD_ZERO(&read_set);
|
||||||
|
//FD_ZERO(&write_set);
|
||||||
|
//FD_SET(listen_fd, &read_set);
|
||||||
|
//FD_SET(connect_fd, &write_set);
|
||||||
|
|
||||||
|
HANDLE thread = CreateThread(NULL, 0, MyThreadFunction, &connect_fd, 0, NULL);
|
||||||
|
|
||||||
|
//sin_size = sizeof(their_addr);
|
||||||
|
//accept_fd = accept(listen_fd, (struct sockaddr *)&their_addr, &sin_size);
|
||||||
|
//Assert::AreEqual(accept_fd, -1, L"", LINE_INFO());
|
||||||
|
//Assert::AreEqual(errno, EAGAIN, L"", LINE_INFO());
|
||||||
|
|
||||||
|
ret = connect(connect_fd, servinfo->ai_addr, servinfo->ai_addrlen);
|
||||||
|
Assert::AreEqual(ret, 0, L"", LINE_INFO());
|
||||||
|
|
||||||
|
WaitForSingleObject(thread, INFINITE);
|
||||||
|
CloseHandle(thread);
|
||||||
|
|
||||||
|
int i = 9;
|
||||||
|
/* accept_fd = accept(listen_fd, (struct sockaddr *)&their_addr, &sin_size);
|
||||||
|
Assert::AreNotEqual(accept_fd, -1, L"", LINE_INFO());
|
||||||
|
*/
|
||||||
|
/* ret = connect(connect_fd, servinfo->ai_addr, servinfo->ai_addrlen);
|
||||||
|
Assert::AreEqual(ret, 0, L"", LINE_INFO());*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(TestMethod)
|
||||||
|
{
|
||||||
fd_set* set = (fd_set*)malloc(sizeof(fd_set));
|
fd_set* set = (fd_set*)malloc(sizeof(fd_set));
|
||||||
|
|
||||||
FD_ZERO(set);
|
FD_ZERO(set);
|
||||||
@ -87,82 +226,6 @@ namespace UnitTests
|
|||||||
Assert::AreEqual(0, FD_ISSET(0, set), L"", LINE_INFO());
|
Assert::AreEqual(0, FD_ISSET(0, set), L"", LINE_INFO());
|
||||||
Assert::AreEqual(0, FD_ISSET(1, set), L"", LINE_INFO());
|
Assert::AreEqual(0, FD_ISSET(1, set), L"", LINE_INFO());
|
||||||
Assert::AreEqual(0, FD_ISSET(2, set), L"", LINE_INFO());
|
Assert::AreEqual(0, FD_ISSET(2, set), L"", LINE_INFO());
|
||||||
|
|
||||||
w32posix_initialize();
|
|
||||||
int sockfd, new_fd; // listen on sock_fd, new connection on new_fd
|
|
||||||
struct addrinfo hints, *servinfo, *p;
|
|
||||||
struct sockaddr_storage their_addr; // connector's address information
|
|
||||||
socklen_t sin_size;
|
|
||||||
int yes = 1;
|
|
||||||
int rv;
|
|
||||||
#define PORT "3490" // the port users will be connecting to
|
|
||||||
|
|
||||||
#define BACKLOG 10 // how many pending connections queue will hold
|
|
||||||
|
|
||||||
memset(&hints, 0, sizeof hints);
|
|
||||||
hints.ai_family = AF_UNSPEC;
|
|
||||||
hints.ai_socktype = SOCK_STREAM;
|
|
||||||
hints.ai_flags = AI_PASSIVE; // use my IP
|
|
||||||
|
|
||||||
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
|
|
||||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop through all the results and bind to the first we can
|
|
||||||
for (p = servinfo; p != NULL; p = p->ai_next) {
|
|
||||||
if ((sockfd = socket(p->ai_family, p->ai_socktype,
|
|
||||||
p->ai_protocol)) == -1) {
|
|
||||||
perror("server: socket");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&yes,
|
|
||||||
sizeof(int)) == -1) {
|
|
||||||
perror("setsockopt");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
|
|
||||||
close(sockfd);
|
|
||||||
perror("server: bind");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
freeaddrinfo(servinfo); // all done with this structure
|
|
||||||
|
|
||||||
if (p == NULL) {
|
|
||||||
fprintf(stderr, "server: failed to bind\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listen(sockfd, BACKLOG) == -1) {
|
|
||||||
perror("listen");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fcntl(sockfd, F_SETFL, O_NONBLOCK);
|
|
||||||
|
|
||||||
fd_set read_set, write_set, except_set;
|
|
||||||
|
|
||||||
ZeroMemory(&read_set, sizeof(fd_set));
|
|
||||||
ZeroMemory(&write_set, sizeof(fd_set));
|
|
||||||
ZeroMemory(&except_set, sizeof(fd_set));
|
|
||||||
|
|
||||||
FD_SET(sockfd, &read_set);
|
|
||||||
struct timeval timeout;
|
|
||||||
timeout.tv_sec = 300;
|
|
||||||
timeout.tv_usec = 0;
|
|
||||||
int ret = select(sockfd, &read_set, &write_set, &except_set, &timeout);
|
|
||||||
|
|
||||||
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -19,11 +19,15 @@ void debug_initialize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void debug_done() {
|
void debug_done() {
|
||||||
fclose(log);
|
if (log)
|
||||||
|
fclose(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void write_log(const char *source_name, const char *function_name, int line_num, const char *fmt, ...) {
|
void write_log(const char *source_name, const char *function_name, int line_num, const char *fmt, ...) {
|
||||||
|
if (!log)
|
||||||
|
return;
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
fprintf(log,"\n%s:%s:%d: ", source_name, function_name, line_num);
|
fprintf(log,"\n%s:%s:%d: ", source_name, function_name, line_num);
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
@ -217,13 +217,14 @@ struct w32_io* socketio_socket(int domain, int type, int protocol) {
|
|||||||
return pio;
|
return pio;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SET_ERRNO_ON_ERROR(ret) \
|
#define SET_ERRNO_ON_ERROR(expr) \
|
||||||
do { \
|
do { \
|
||||||
if ((ret) == SOCKET_ERROR) { \
|
int ret = (expr); \
|
||||||
|
if (ret == SOCKET_ERROR) { \
|
||||||
errno = errno_from_WSALastError(); \
|
errno = errno_from_WSALastError(); \
|
||||||
debug("ERROR:%d, io:%p", errno, pio); \
|
debug("ERROR:%d", errno); \
|
||||||
} \
|
} \
|
||||||
return (ret); \
|
return ret; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen) {
|
int socketio_setsockopt(struct w32_io* pio, int level, int optname, const char* optval, int optlen) {
|
||||||
@ -248,7 +249,7 @@ int socketio_listen(struct w32_io* pio, int backlog) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen) {
|
int socketio_bind(struct w32_io* pio, const struct sockaddr *name, int namelen) {
|
||||||
SET_ERRNO_ON_ERROR(bind(pio->sock, name, namelen));
|
SET_ERRNO_ON_ERROR(bind(pio->sock, name, namelen));
|
||||||
}
|
}
|
||||||
|
|
||||||
int socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) {
|
int socketio_recv(struct w32_io* pio, void *buf, size_t len, int flags) {
|
||||||
@ -523,7 +524,7 @@ int socketio_close(struct w32_io* pio) {
|
|||||||
struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) {
|
struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* addrlen) {
|
||||||
struct w32_io *accept_io = NULL;
|
struct w32_io *accept_io = NULL;
|
||||||
int iResult = 0;
|
int iResult = 0;
|
||||||
struct acceptEx_context* context = (struct acceptEx_context*)pio->context;
|
struct acceptEx_context* context;
|
||||||
|
|
||||||
debug2("io:%p", pio);
|
debug2("io:%p", pio);
|
||||||
//start io if not already started
|
//start io if not already started
|
||||||
@ -553,11 +554,22 @@ struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* a
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context = (struct acceptEx_context*)pio->context;
|
||||||
|
pio->read_details.pending = FALSE;
|
||||||
|
ResetEvent(pio->read_overlapped.hEvent);
|
||||||
|
|
||||||
|
if (pio->read_details.error)
|
||||||
|
{
|
||||||
|
errno = errno_from_WSAError(pio->read_details.error);
|
||||||
|
debug("ERROR: async io completed with error: %d, io:%p", errno, pio);
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
if (0 != setsockopt(context->accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock)))
|
if (0 != setsockopt(context->accept_socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&pio->sock, sizeof(pio->sock)))
|
||||||
{
|
{
|
||||||
errno = errno_from_WSALastError();
|
errno = errno_from_WSALastError();
|
||||||
debug("ERROR: setsockopt failed:%d, io:%p", errno, pio);
|
debug("ERROR: setsockopt failed:%d, io:%p", errno, pio);
|
||||||
return NULL;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
accept_io = (struct w32_io*)malloc(sizeof(struct w32_io));
|
accept_io = (struct w32_io*)malloc(sizeof(struct w32_io));
|
||||||
@ -565,33 +577,58 @@ struct w32_io* socketio_accept(struct w32_io* pio, struct sockaddr* addr, int* a
|
|||||||
{
|
{
|
||||||
errno = ENOMEM;
|
errno = ENOMEM;
|
||||||
debug("ERROR:%d, io:%p", errno, pio);
|
debug("ERROR:%d, io:%p", errno, pio);
|
||||||
return NULL;
|
goto on_error;
|
||||||
}
|
}
|
||||||
memset(accept_io, 0, sizeof(struct w32_io));
|
memset(accept_io, 0, sizeof(struct w32_io));
|
||||||
|
|
||||||
accept_io->sock = context->accept_socket;
|
accept_io->sock = context->accept_socket;
|
||||||
accept_io->type = SOCK_FD;
|
accept_io->type = SOCK_FD;
|
||||||
context->accept_socket = INVALID_SOCKET;
|
context->accept_socket = INVALID_SOCKET;
|
||||||
pio->read_details.pending = FALSE;
|
|
||||||
ResetEvent(pio->read_overlapped.hEvent);
|
|
||||||
debug2("accept io:%p", accept_io);
|
debug2("accept io:%p", accept_io);
|
||||||
|
|
||||||
|
//TODO : fill in addr
|
||||||
return accept_io;
|
return accept_io;
|
||||||
|
|
||||||
|
on_error:
|
||||||
|
if (context->accept_socket != INVALID_SOCKET) {
|
||||||
|
closesocket(context->accept_socket);
|
||||||
|
context->accept_socket = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) {
|
int socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int namelen) {
|
||||||
|
|
||||||
struct sockaddr_in tmp_addr;
|
struct sockaddr_in tmp_addr4;
|
||||||
|
struct sockaddr_in6 tmp_addr6;
|
||||||
|
SOCKADDR* tmp_addr;
|
||||||
|
size_t tmp_addr_len;
|
||||||
DWORD tmp_bytes;
|
DWORD tmp_bytes;
|
||||||
GUID connectex_guid = WSAID_CONNECTEX;
|
GUID connectex_guid = WSAID_CONNECTEX;
|
||||||
LPFN_CONNECTEX ConnectEx;
|
LPFN_CONNECTEX ConnectEx;
|
||||||
|
|
||||||
|
if (name->sa_family == AF_INET6) {
|
||||||
//TODO - add support for DGRAM socket, below works only for STREAM sockets
|
ZeroMemory(&tmp_addr6, sizeof(tmp_addr6));
|
||||||
ZeroMemory(&tmp_addr, sizeof(tmp_addr));
|
tmp_addr6.sin6_family = AF_INET6;
|
||||||
tmp_addr.sin_family = AF_UNSPEC;
|
tmp_addr6.sin6_port = 0;
|
||||||
tmp_addr.sin_addr.s_addr = INADDR_ANY;
|
tmp_addr = (SOCKADDR*)&tmp_addr6;
|
||||||
tmp_addr.sin_port = 0;
|
tmp_addr_len = sizeof(tmp_addr6);
|
||||||
if (SOCKET_ERROR == bind(pio->sock, (SOCKADDR*)&tmp_addr, sizeof(tmp_addr)))
|
}
|
||||||
|
else if (name->sa_family == AF_INET) {
|
||||||
|
ZeroMemory(&tmp_addr4, sizeof(tmp_addr4));
|
||||||
|
tmp_addr4.sin_family = AF_INET;
|
||||||
|
tmp_addr4.sin_port = 0;
|
||||||
|
tmp_addr = (SOCKADDR*)&tmp_addr4;
|
||||||
|
tmp_addr_len = sizeof(tmp_addr4);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
errno = ENOTSUP;
|
||||||
|
debug("ERROR: unsuppored address family:%d, io:%p", name->sa_family, pio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SOCKET_ERROR == bind(pio->sock, tmp_addr, tmp_addr_len))
|
||||||
{
|
{
|
||||||
errno = errno_from_WSALastError();
|
errno = errno_from_WSALastError();
|
||||||
debug("ERROR: bind failed :%d, io:%p", errno, pio);
|
debug("ERROR: bind failed :%d, io:%p", errno, pio);
|
||||||
@ -614,7 +651,7 @@ int socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int name
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TRUE == ConnectEx(pio->sock, name, namelen, NULL, 0, pio->write_details.completed, &pio->write_overlapped))
|
if (TRUE == ConnectEx(pio->sock, name, namelen, NULL, 0, NULL, &pio->write_overlapped))
|
||||||
{
|
{
|
||||||
//set completion event
|
//set completion event
|
||||||
SetEvent(pio->write_overlapped.hEvent);
|
SetEvent(pio->write_overlapped.hEvent);
|
||||||
@ -632,7 +669,7 @@ int socketio_connectex(struct w32_io* pio, const struct sockaddr* name, int name
|
|||||||
}
|
}
|
||||||
|
|
||||||
pio->write_details.pending = TRUE;
|
pio->write_details.pending = TRUE;
|
||||||
pio->type == CONNECT_FD;
|
pio->type = CONNECT_FD;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,6 +702,16 @@ int socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namele
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//close event handle
|
||||||
|
CloseHandle(pio->write_overlapped.hEvent);
|
||||||
|
pio->write_overlapped.hEvent = 0;
|
||||||
|
|
||||||
|
if (pio->write_details.error) {
|
||||||
|
errno = errno_from_WSAError(pio->write_details.error);
|
||||||
|
debug("ERROR: async io completed with error: %d, io:%p", errno, pio);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (0 != setsockopt(pio->sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, NULL, 0))
|
if (0 != setsockopt(pio->sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, NULL, 0))
|
||||||
{
|
{
|
||||||
errno = errno_from_WSALastError();
|
errno = errno_from_WSALastError();
|
||||||
@ -672,9 +719,7 @@ int socketio_connect(struct w32_io* pio, const struct sockaddr* name, int namele
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//close event handle
|
|
||||||
CloseHandle(pio->write_overlapped.hEvent);
|
|
||||||
pio->write_overlapped.hEvent = 0;
|
|
||||||
pio->type = SOCK_FD;
|
pio->type = SOCK_FD;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -693,8 +738,11 @@ BOOL socketio_is_io_available(struct w32_io* pio, BOOL rd) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (pending && WSAGetLastError() != WSA_IO_INCOMPLETE) {
|
if (pending && WSAGetLastError() != WSA_IO_INCOMPLETE) {
|
||||||
//unexpected error;
|
if (pio->type == LISTEN_FD)
|
||||||
debug("ERROR:Unxpected State. io:%p, WSAError:%d", pio, WSAGetLastError());
|
pio->read_details.error = WSAGetLastError();
|
||||||
|
else
|
||||||
|
pio->write_details.error = WSAGetLastError();
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -725,6 +773,10 @@ int socketio_on_select(struct w32_io* pio, BOOL rd) {
|
|||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if (pio->type == CONNECT_FD) {
|
||||||
|
//nothing to do for connect
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
else if (rd) {
|
else if (rd) {
|
||||||
if (socketio_WSARecv(pio, NULL) != 0)
|
if (socketio_WSARecv(pio, NULL) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user