SOCKET skt_connect(skt_ip_t ip, int port, int timeout) { struct sockaddr_in addr=skt_build_addr(ip,port); int ok, begin; SOCKET ret; begin = time(0); while (time(0)-begin < timeout) { ret = socket(AF_INET, SOCK_STREAM, 0); if (ret==SOCKET_ERROR) { if (skt_should_retry()) continue; else return skt_abort(93512,"Error creating socket"); } ok = connect(ret, (struct sockaddr *)&(addr), sizeof(addr)); if (ok != SOCKET_ERROR) return ret;/*Good connect*/ else { /*Bad connect*/ skt_close(ret); if (skt_should_retry()) continue; else return skt_abort(93515,"Error connecting to socket\n"); } } /*Timeout*/ return skt_abort(93517,"Timeout in socket connect\n"); }
SOCKET skt_server_ip(unsigned int *port,skt_ip_t *ip) { SOCKET ret; socklen_t len; int on = 1; /* for setsockopt */ int connPort=(port==NULL)?0:*port; struct sockaddr_in addr=skt_build_addr((ip==NULL)?_skt_invalid_ip:*ip,connPort); retry: ret = socket(PF_INET, SOCK_STREAM, 0); if (ret == SOCKET_ERROR) { if (skt_should_retry()) goto retry; else return skt_abort(93483,"Error creating server socket."); } /* Prevents 3-minute socket reuse timeout after a server crash. */ setsockopt(ret, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on)); if (bind(ret, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) return skt_abort(93484,"Error binding server socket. Is another process listening on that port already?"); if (listen(ret,5) == SOCKET_ERROR) return skt_abort(93485,"Error listening on server socket."); len = sizeof(addr); if (getsockname(ret, (struct sockaddr *)&addr, &len) == SOCKET_ERROR) return skt_abort(93486,"Error getting name on server socket."); if (port!=NULL) *port = (int)ntohs(addr.sin_port); if (ip!=NULL) memcpy(ip, &addr.sin_addr, sizeof(*ip)); return ret; }
SOCKET skt_datagram(unsigned int *port, int bufsize) { int connPort=(port==NULL)?0:*port; struct sockaddr_in addr=skt_build_addr(_skt_invalid_ip,connPort); socklen_t len; SOCKET ret; retry: ret = socket(AF_INET,SOCK_DGRAM,0); if (ret == SOCKET_ERROR) { if (skt_should_retry()) goto retry; return skt_abort(93490,"Error creating datagram socket."); } if (bind(ret, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR) return skt_abort(93491,"Error binding datagram socket."); len = sizeof(addr); if (getsockname(ret, (struct sockaddr *)&addr , &len)) return skt_abort(93492,"Error getting address on datagram socket."); if (bufsize) { len = sizeof(int); if (setsockopt(ret, SOL_SOCKET , SO_RCVBUF , (char *)&bufsize, len) == SOCKET_ERROR) return skt_abort(93495,"Error on RCVBUF sockopt for datagram socket."); if (setsockopt(ret, SOL_SOCKET , SO_SNDBUF , (char *)&bufsize, len) == SOCKET_ERROR) return skt_abort(93496,"Error on SNDBUF sockopt for datagram socket."); } if (port!=NULL) *port = (int)ntohs(addr.sin_port); return ret; }
SOCKET skt_connect(skt_ip_t ip, int port, int timeout) { struct sockaddr_in addr=skt_build_addr(ip,port); int ok, begin; SOCKET ret; begin = time(0); while (time(0)-begin < timeout) { ret = socket(AF_INET, SOCK_STREAM, 0); if (ret==SOCKET_ERROR) { if (skt_should_retry()) continue; else return skt_abort(-1, 93512, "Error creating socket"); } ok = connect(ret, (struct sockaddr *)&(addr), sizeof(addr)); if (ok != SOCKET_ERROR) return ret;/*Good connect*/ else { /*Bad connect*/ skt_close(ret); if (skt_should_retry()) continue; else { #if ! defined(_WIN32) || defined(__CYGWIN__) if (ERRNO == ETIMEDOUT) continue; /* time out is fine */ #endif return skt_abort(-1, 93515, "Error connecting to socket\n"); } } } /*Timeout*/ if (timeout==60) return skt_abort(-1, 93517, "Timeout in socket connect\n"); return INVALID_SOCKET; }
/* initnode node table reply format: +------------------------------------------------------- | 4 bytes | Number of nodes n ^ | | (big-endian binary integer) 4+12*n bytes +------------------------------------------------- | ^ | (one entry for each node) ^ | | | 4 bytes | Number of PEs for this node | | n | 4 bytes | IP address of this node 12*n bytes | | | 4 bytes | Data (UDP) port of this node | | v | | (big-endian binary integers) v v ---+---------------------------------------------------- */ static void node_addresses_store(ChMessage *msg) { ChMessageInt_t *n32=(ChMessageInt_t *)msg->data; ChNodeinfo *d=(ChNodeinfo *)(n32+1); int nodestart; int i,j,n; MACHSTATE(1,"node_addresses_store {"); _Cmi_numnodes=ChMessageInt(n32[0]); if ((sizeof(ChMessageInt_t)+sizeof(ChNodeinfo)*_Cmi_numnodes) !=(unsigned int)msg->len) {printf("Node table has inconsistent length!");machine_exit(1);} nodes = (OtherNode)malloc(_Cmi_numnodes * sizeof(struct OtherNodeStruct)); nodestart=0; for (i=0; i<_Cmi_numnodes; i++) { nodes[i].nodestart = nodestart; nodes[i].nodesize = ChMessageInt(d[i].nPE); MACHSTATE2(3,"node %d nodesize %d",i,nodes[i].nodesize); nodes[i].mach_id = ChMessageInt(d[i].mach_id); nodes[i].IP=d[i].IP; if (i==_Cmi_mynode) { Cmi_nodestart=nodes[i].nodestart; _Cmi_mynodesize=nodes[i].nodesize; Cmi_self_IP=nodes[i].IP; } nodes[i].dataport = ChMessageInt(d[i].dataport); nodes[i].addr = skt_build_addr(nodes[i].IP,nodes[i].dataport); #if CMK_USE_TCP nodes[i].sock = INVALID_SOCKET; #endif nodestart+=nodes[i].nodesize; } _Cmi_numpes=nodestart; n = _Cmi_numpes; #ifdef CMK_CPV_IS_SMP n += _Cmi_numnodes; #endif nodes_by_pe = (OtherNode*)malloc(n * sizeof(OtherNode)); _MEMCHECK(nodes_by_pe); for (i=0; i<_Cmi_numnodes; i++) { OtherNode node = nodes + i; OtherNode_init(node); for (j=0; j<node->nodesize; j++) { nodes_by_pe[j + node->nodestart] = node; } } #ifdef CMK_CPV_IS_SMP /* index for communication threads */ for (i=_Cmi_numpes; i<_Cmi_numpes+_Cmi_numnodes; i++) { OtherNode node = nodes + i-_Cmi_numpes; nodes_by_pe[i] = node; } #endif MACHSTATE(1,"} node_addresses_store"); }
// Server loop to handle incoming connections void TCPServer::loop(){ std::unique_lock<std::mutex> connectionLock(_mutex, std::defer_lock); while(!_dead){ skt_ip_t client_ip; // IP & port of other end of connection unsigned int client_port; int cSocket = skt_accept(_socket, &client_ip, &client_port); sockaddr_in address = skt_build_addr(client_ip, client_port); sockaddr client_addr = *((sockaddr *)(&address)); connectionLock.lock(); std::shared_ptr<TCPConnection> newCon = makeConnection(cSocket, client_addr); newCon -> start(); _connections[to_string(client_addr)] = newCon; connectionLock.unlock(); } }