Skip to content

Commit

Permalink
allow ipv4 and 6 connections
Browse files Browse the repository at this point in the history
  • Loading branch information
andy5995 committed Aug 15, 2022
1 parent e63d814 commit 7152483
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 63 deletions.
2 changes: 2 additions & 0 deletions source/shared_lib/include/platform/posix/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ class Socket {

static int getBroadCastPort() { return broadcast_portno; }
static void setBroadCastPort(int value) { broadcast_portno = value; }
static int getIpStr(struct addrinfo *ptr, char *buf);
struct addrinfo *getAddrInfo(const int port);
static std::vector<std::string> getLocalIPAddressList();

// Int lookup is socket fd while bool result is whether or not that socket was signalled for reading
Expand Down
181 changes: 118 additions & 63 deletions source/shared_lib/sources/platform/posix/socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,7 @@ string getNetworkInterfaceBroadcastAddress(string ipAddress)
//printf(" Found interface: name=[%s] desc=[%s] address=[%s] netmask=[%s] broadcastAddr=[%s]\n", name, desc?desc:"unavailable", ifaAddrStr, maskAddrStr, dstAddrStr);
if(strcmp(ifaAddrStr,ipAddress.c_str()) == 0) {
broadCastAddress = dstAddrStr;
}
}
}

if(pAdapterInfo) free(pAdapterInfo);
Expand All @@ -661,44 +661,99 @@ string getNetworkInterfaceBroadcastAddress(string ipAddress)
return broadCastAddress;
}

int Socket::getIpStr(struct addrinfo *ptr, char *buf) {
void *addr;
if (ptr->ai_family == AF_INET) {
struct sockaddr_in *ipv4 = (struct sockaddr_in *) ptr->ai_addr;
addr = &(ipv4->sin_addr);
}
else {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
addr = &(ipv6->sin6_addr);
}

const char *ipStr = inet_ntop(ptr->ai_family, addr, buf, INET6_ADDRSTRLEN);
if (ipStr == NULL) {
perror("inet_ntop:");
return -1;
}

return 0;
}

uint32 Socket::getConnectedIPAddress(string IP) {
sockaddr_in addr;
memset(&addr, 0, sizeof(addr));
unsigned char addr[sizeof(struct in6_addr)];
if(IP == "") {
IP = connectedIpAddress;
}
int r = inet_pton(AF_INET, IP.c_str(), addr);
if (r != 0) {
// handle error
}
return SockAddrToUint32((struct in_addr *)&addr);;
}

addr.sin_family= AF_INET;
if(IP == "") {
IP = connectedIpAddress;
}
addr.sin_addr.s_addr= inet_addr(IP.c_str());
//addr.sin_port= htons(port);
// returns a pointer to a memory-allocated addrinfo struct which must
// be freed later with freeaddrinfo()
struct addrinfo *Socket::getAddrInfo(const int port) {
struct addrinfo hints;
struct addrinfo *result;

/* Obtain address(es) matching host/port */
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;

return SockAddrToUint32((struct sockaddr *)&addr);
char strPort[BUFSIZ];
size_t n = snprintf (strPort, sizeof strPort, "%d", port);
if (n > sizeof strPort) {
fprintf (stderr, "strPort truncated. This should not happen.");
throw megaglest_runtime_error(strPort);
}

char myhostname[HOST_NAME_MAX]="";
int r=gethostname(myhostname,HOST_NAME_MAX);
if (r != 0) {
fputs("gethostname failed.", stderr);
throw megaglest_runtime_error(myhostname);
}

int s = getaddrinfo(myhostname, strPort, &hints, &result);
if (s != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
throw megaglest_runtime_error(myhostname);
}

return result;
}

std::vector<std::string> Socket::getLocalIPAddressList() {
std::vector<std::string>Socket::getLocalIPAddressList() {
std::vector<std::string> ipList;
/* get my host name */
char myhostname[101]="";
gethostname(myhostname,100);

struct hostent* myhostent = gethostbyname(myhostname);
if(myhostent) {
// get all host IP addresses (Except for loopback)
char myhostaddr[101] = "";
for(int ipIdx = 0; myhostent->h_addr_list[ipIdx] != NULL; ++ipIdx) {
Ip::Inet_NtoA(SockAddrToUint32((struct in_addr *)myhostent->h_addr_list[ipIdx]), myhostaddr);

//printf("ipIdx = %d [%s]\n",ipIdx,myhostaddr);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] myhostaddr = [%s]\n",__FILE__,__FUNCTION__,__LINE__,myhostaddr);

if(strlen(myhostaddr) > 0 &&
strncmp(myhostaddr,"127.",4) != 0 &&
strncmp(myhostaddr,"0.",2) != 0) {
ipList.push_back(myhostaddr);
}
Socket tmp;
struct addrinfo *result = tmp.getAddrInfo(61357);
char ipStr[INET6_ADDRSTRLEN];
struct addrinfo *ptr = result;

for (ptr; ptr != NULL; ptr = ptr->ai_next)
{
if (tmp.getIpStr(ptr, ipStr) != 0)
throw megaglest_runtime_error("getLocalIPAddressList");

if(strlen(ipStr) > 0 &&
strncmp(ipStr,"127.",4) != 0 &&
strncmp(ipStr,"0.",2) != 0) {
ipList.push_back(ipStr);
}
}

freeaddrinfo(result);

Socket::getLocalIPAddressListForPlatform(ipList);
return ipList;
}
Expand Down Expand Up @@ -905,7 +960,7 @@ Socket::Socket() {

this->connectedIpAddress = "";

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sock = socket(AF_INET, SOCK_STREAM, 0);
if(isSocketValid() == false) {
throwException("Error creating socket");
}
Expand Down Expand Up @@ -1381,7 +1436,7 @@ int Socket::send(const void *data, int dataSize) {
int totalBytesSent = bytesSent;
int attemptCount = 0;


time_t tStartTimer = time(NULL);
while(((bytesSent > 0 && totalBytesSent < dataSize) ||
(bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN)) &&
Expand Down Expand Up @@ -2392,49 +2447,49 @@ bool ServerSocket::isBroadCastThreadRunning() {

void ServerSocket::bind(int port) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d port = %d, portBound = %d START\n",__FILE__,__FUNCTION__,__LINE__,port,portBound);

boundPort = port;

if(isSocketValid() == false) {
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(isSocketValid() == false) {
throwException("Error creating socket");
}
setBlock(false);
printf("boundPort = %d\n", boundPort);
struct addrinfo *hostAddrInfo = Socket::getAddrInfo(boundPort);
if (hostAddrInfo == NULL) {
fputs("getAddrinfoInfo() returned NULL", stderr);
exit(EXIT_FAILURE);
}

//sockaddr structure
sockaddr_in addr;
addr.sin_family= AF_INET;
if(this->bindSpecificAddress != "") {
addr.sin_addr.s_addr= inet_addr(this->bindSpecificAddress.c_str());
}
else {
addr.sin_addr.s_addr= INADDR_ANY;
}
addr.sin_port= htons(port);
addr.sin_zero[0] = 0;
struct addrinfo *ptr = hostAddrInfo;
for (ptr; ptr != NULL; ptr = ptr->ai_next)
{
sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
if(sock == -1) {
continue;
}

int val = 1;
setBlock(false);
int val = 1;

#ifndef WIN32
int opt_result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
#else
int opt_result = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
#endif

int err= ::bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
if(err < 0) {
char szBuf[8096]="";
snprintf(szBuf, 8096,"In [%s::%s] Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE ", address [%s] port = %d err = %d, error = %s opt_result = %d\n",__FILE__,__FUNCTION__,sock,this->bindSpecificAddress.c_str(),port,err,getLastSocketErrorFormattedText().c_str(),opt_result);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"%s",szBuf);
char ipStr[INET6_ADDRSTRLEN];
if (Socket::getIpStr(ptr, ipStr) != 0) {
throw megaglest_runtime_error("");
}

snprintf(szBuf, 8096,"Error binding socket sock = " PLATFORM_SOCKET_FORMAT_TYPE ", address [%s] port = %d err = %d, error = %s\n",sock,this->bindSpecificAddress.c_str(),port,err,getLastSocketErrorFormattedText().c_str());
throw megaglest_runtime_error(szBuf);
}
portBound = true;
printf("Binding to %s:%d...", ipStr, boundPort);

if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d port = %d, portBound = %d END\n",__FILE__,__FUNCTION__,__LINE__,port,portBound);
if ((::bind (sock, (struct sockaddr *)hostAddrInfo->ai_addr, sizeof(struct sockaddr))) < 0) {
puts("fail");
perror("bind");
close(sock);
exit(EXIT_FAILURE);
}
puts("ok");

portBound = true;
}
freeaddrinfo(hostAddrInfo);
}

void ServerSocket::disconnectSocket() {
Expand All @@ -2449,7 +2504,7 @@ void ServerSocket::listen(int connectionQueueSize) {
if(isSocketValid() == false) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);

sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
sock = socket(AF_INET, SOCK_STREAM, 0);
if(isSocketValid() == false) {
throwException("Error creating socket");
}
Expand Down

0 comments on commit 7152483

Please sign in to comment.