Add createSocket() helper to reduce code duplication

This commit is contained in:
Cameron Gutman
2020-08-29 18:54:11 -07:00
parent feaca5b5b0
commit 9064d4931f
3 changed files with 63 additions and 65 deletions
+3 -19
View File
@@ -109,9 +109,10 @@ unsigned int LiTestClientConnectivity(const char* testServer, unsigned short ref
for (i = 0; i < PORT_FLAGS_MAX_COUNT; i++) { for (i = 0; i < PORT_FLAGS_MAX_COUNT; i++) {
if (testPortFlags & (1 << i)) { if (testPortFlags & (1 << i)) {
sockets[i] = socket(address.ss_family, sockets[i] = createSocket(address.ss_family,
LiGetProtocolFromPortFlagIndex(i) == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM, LiGetProtocolFromPortFlagIndex(i) == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM,
LiGetProtocolFromPortFlagIndex(i)); LiGetProtocolFromPortFlagIndex(i),
1);
if (sockets[i] == INVALID_SOCKET) { if (sockets[i] == INVALID_SOCKET) {
err = LastSocketFail(); err = LastSocketFail();
Limelog("Failed to create socket: %d\n", err); Limelog("Failed to create socket: %d\n", err);
@@ -119,25 +120,8 @@ unsigned int LiTestClientConnectivity(const char* testServer, unsigned short ref
goto Exit; goto Exit;
} }
#ifdef LC_DARWIN
{
// Disable SIGPIPE on iOS
int val = 1;
setsockopt(sockets[i], SOL_SOCKET, SO_NOSIGPIPE, (char*)&val, sizeof(val));
}
#endif
((struct sockaddr_in6*)&address)->sin6_port = htons(LiGetPortFromPortFlagIndex(i)); ((struct sockaddr_in6*)&address)->sin6_port = htons(LiGetPortFromPortFlagIndex(i));
if (LiGetProtocolFromPortFlagIndex(i) == IPPROTO_TCP) { if (LiGetProtocolFromPortFlagIndex(i) == IPPROTO_TCP) {
// Enable non-blocking I/O for connect timeout support
if (setSocketNonBlocking(sockets[i] , 1) != 0) {
// If non-blocking sockets are not available, TCP tests are not supported
err = LastSocketFail();
Limelog("Failed to enable non-blocking I/O: %d\n", err);
failingPortFlags = ML_TEST_RESULT_INCONCLUSIVE;
goto Exit;
}
// Initiate an asynchronous connection // Initiate an asynchronous connection
err = connect(sockets[i], (struct sockaddr*)&address, address_length); err = connect(sockets[i], (struct sockaddr*)&address, address_length);
if (err < 0) { if (err < 0) {
+27 -14
View File
@@ -180,9 +180,8 @@ SOCKET bindUdpSocket(int addrfamily, int bufferSize) {
LC_ASSERT(addrfamily == AF_INET || addrfamily == AF_INET6); LC_ASSERT(addrfamily == AF_INET || addrfamily == AF_INET6);
s = socket(addrfamily, SOCK_DGRAM, IPPROTO_UDP); s = createSocket(addrfamily, SOCK_DGRAM, IPPROTO_UDP, 0);
if (s == INVALID_SOCKET) { if (s == INVALID_SOCKET) {
Limelog("socket() failed: %d\n", (int)LastSocketError());
return INVALID_SOCKET; return INVALID_SOCKET;
} }
@@ -251,14 +250,11 @@ int setSocketNonBlocking(SOCKET s, int val) {
#endif #endif
} }
SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec) { SOCKET createSocket(int addressFamily, int socketType, int protocol, int nonBlocking) {
SOCKET s; SOCKET s;
struct sockaddr_in6 addr;
int err;
int nonBlocking;
int val; int val;
s = socket(dstaddr->ss_family, SOCK_STREAM, IPPROTO_TCP); s = socket(addressFamily, socketType, protocol);
if (s == INVALID_SOCKET) { if (s == INVALID_SOCKET) {
Limelog("socket() failed: %d\n", (int)LastSocketError()); Limelog("socket() failed: %d\n", (int)LastSocketError());
return INVALID_SOCKET; return INVALID_SOCKET;
@@ -270,6 +266,26 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (char*)&val, sizeof(val)); setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, (char*)&val, sizeof(val));
#endif #endif
if (nonBlocking) {
setSocketNonBlocking(s, 1);
}
return s;
}
SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec) {
SOCKET s;
struct sockaddr_in6 addr;
struct pollfd pfd;
int err;
int val;
// Create a non-blocking TCP socket
s = createSocket(dstaddr->ss_family, SOCK_STREAM, IPPROTO_TCP, 1);
if (s == INVALID_SOCKET) {
return INVALID_SOCKET;
}
// Some broken routers/firewalls (or routes with multiple broken routers) may result in TCP packets // Some broken routers/firewalls (or routes with multiple broken routers) may result in TCP packets
// being dropped without without us receiving an ICMP Fragmentation Needed packet. For example, // being dropped without without us receiving an ICMP Fragmentation Needed packet. For example,
// a router can elect to drop rather than fragment even without DF set. A misconfigured firewall // a router can elect to drop rather than fragment even without DF set. A misconfigured firewall
@@ -312,19 +328,16 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
} }
#endif #endif
// Enable non-blocking I/O for connect timeout support
nonBlocking = setSocketNonBlocking(s, 1) == 0;
// Start connection // Start connection
memcpy(&addr, dstaddr, addrlen); memcpy(&addr, dstaddr, addrlen);
addr.sin6_port = htons(port); addr.sin6_port = htons(port);
err = connect(s, (struct sockaddr*) &addr, addrlen); err = connect(s, (struct sockaddr*) &addr, addrlen);
if (err < 0) { if (err < 0) {
err = (int)LastSocketError(); err = (int)LastSocketError();
if (err != EWOULDBLOCK && err != EAGAIN && err != EINPROGRESS) {
goto Exit;
}
} }
if (nonBlocking) {
struct pollfd pfd;
// Wait for the connection to complete or the timeout to elapse // Wait for the connection to complete or the timeout to elapse
pfd.fd = s; pfd.fd = s;
@@ -357,8 +370,8 @@ SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen,
// Disable non-blocking I/O now that the connection is established // Disable non-blocking I/O now that the connection is established
setSocketNonBlocking(s, 0); setSocketNonBlocking(s, 0);
}
Exit:
if (err != 0) { if (err != 0) {
Limelog("connect() failed: %d\n", err); Limelog("connect() failed: %d\n", err);
closeSocket(s); closeSocket(s);
+1
View File
@@ -51,6 +51,7 @@ typedef socklen_t SOCKADDR_LEN;
#define URLSAFESTRING_LEN (INET6_ADDRSTRLEN+2) #define URLSAFESTRING_LEN (INET6_ADDRSTRLEN+2)
void addrToUrlSafeString(struct sockaddr_storage* addr, char* string); void addrToUrlSafeString(struct sockaddr_storage* addr, char* string);
SOCKET createSocket(int addressFamily, int socketType, int protocol, int nonBlocking);
int resolveHostName(const char* host, int family, int tcpTestPort, struct sockaddr_storage* addr, SOCKADDR_LEN* addrLen); int resolveHostName(const char* host, int family, int tcpTestPort, struct sockaddr_storage* addr, SOCKADDR_LEN* addrLen);
SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec); SOCKET connectTcpSocket(struct sockaddr_storage* dstaddr, SOCKADDR_LEN addrlen, unsigned short port, int timeoutSec);
int sendMtuSafe(SOCKET s, char* buffer, int size); int sendMtuSafe(SOCKET s, char* buffer, int size);