44 #include <arpa/inet.h>
46 #include <netinet/tcp.h>
47 #include <sys/socket.h>
48 #include <sys/types.h>
57 #include "debug/DistEthernet.hh"
58 #include "debug/DistEthernetCmd.hh"
62 #if defined(__FreeBSD__)
63 #include <netinet/in.h>
68 #if defined(__APPLE__) || defined(__MACH__)
70 #define MSG_NOSIGNAL SO_NOSIGPIPE
80 unsigned dist_rank,
unsigned dist_size,
84 DistIface(dist_rank, dist_size, sync_start, sync_repeat,
em, use_pseudo_op,
85 is_switch, num_nodes), serverName(server_name),
86 serverPort(server_port), isSwitch(is_switch), listening(false)
90 DPRINTF(DistEthernet,
"TCPIface(listen): Can't bind port %d\n",
101 for (
int i = 0;
i <
size;
i++) {
103 DPRINTF(DistEthernet,
"First connection, waiting for link info\n");
105 panic(
"Failed to receive link info");
115 panic(
"Socket already listening!");
117 struct sockaddr_in sockaddr;
120 fdStatic = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
123 sockaddr.sin_family = PF_INET;
124 sockaddr.sin_addr.s_addr = INADDR_ANY;
125 sockaddr.sin_port = htons(port);
127 memset(&sockaddr.sin_zero, 0,
sizeof(sockaddr.sin_zero));
128 ret = ::bind(
fdStatic, (
struct sockaddr *)&sockaddr,
sizeof (sockaddr));
131 if (ret == -1 && errno != EADDRINUSE)
132 panic(
"ListenSocket(listen): bind() failed!");
137 if (errno != EADDRINUSE)
138 panic(
"ListenSocket(listen): listen() failed!");
151 static unsigned cur_rank = 0;
152 static unsigned cur_id = 0;
160 return cn.first.rank == cur_rank;
162 assert(iface0 !=
nodes.end());
163 assert(iface0->first.distIfaceId == 0);
164 sock = iface0->second;
168 DPRINTF(DistEthernet,
"Next connection, waiting for link info\n");
170 panic(
"Failed to receive link info");
171 assert(
ni.rank == cur_rank);
172 assert(
ni.distIfaceId == cur_id);
174 inform(
"Link okay (iface:%d -> (node:%d, iface:%d))",
176 if (
ni.distIfaceId <
ni.distIfaceNum - 1) {
193 DPRINTF(DistEthernet,
"Connected, waiting for ack (distIfaceId:%d\n",
196 panic(
"Failed to receive ack");
207 struct sockaddr_in sockaddr;
208 socklen_t slen =
sizeof (sockaddr);
212 if (setsockopt(
sock, IPPROTO_TCP, TCP_NODELAY, (
char *)&
i,
214 warn(
"ListenSocket(accept): setsockopt() TCP_NODELAY failed!");
221 struct addrinfo addr_hint, *addr_results;
226 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
227 panic_if(
sock < 0,
"socket() failed: %s", strerror(errno));
230 if (setsockopt(
sock, IPPROTO_TCP, TCP_NODELAY, (
char *)&fl,
sizeof(fl)) < 0)
231 warn(
"ConnectSocket(connect): setsockopt() TCP_NODELAY failed!");
233 bzero(&addr_hint,
sizeof(addr_hint));
234 addr_hint.ai_family = AF_INET;
235 addr_hint.ai_socktype = SOCK_STREAM;
236 addr_hint.ai_protocol = IPPROTO_TCP;
238 ret = getaddrinfo(
serverName.c_str(), port_str.c_str(),
239 &addr_hint, &addr_results);
240 panic_if(ret < 0,
"getaddrinf() failed: %s", strerror(errno));
242 DPRINTF(DistEthernet,
"Connecting to %s:%s\n",
245 ret =
::connect(
sock, (
struct sockaddr *)(addr_results->ai_addr),
246 addr_results->ai_addrlen);
247 panic_if(ret < 0,
"connect() failed: %s", strerror(errno));
249 freeaddrinfo(addr_results);
265 ret = ::send(
sock, buf, length, MSG_NOSIGNAL);
267 if (errno == ECONNRESET || errno == EPIPE) {
268 exitSimLoop(
"Message server closed connection, simulation "
271 panic(
"send() failed: %s", strerror(errno));
274 panic_if(ret != length,
"send() failed");
282 ret = ::recv(
sock, buf, length, MSG_WAITALL );
284 if (errno == ECONNRESET || errno == EPIPE)
285 inform(
"recv(): %s", strerror(errno));
287 panic(
"recv() failed: %s", strerror(errno));
288 }
else if (ret == 0) {
289 inform(
"recv(): Connection closed");
290 }
else if (ret != length)
291 panic(
"recv() failed");
293 return (ret == length);
306 DPRINTF(DistEthernetCmd,
"TCPIface::sendCmd() type: %d\n",
307 static_cast<int>(
header.msgType));
319 DPRINTF(DistEthernetCmd,
"TCPIface::recvHeader() type: %d ret: %d\n",
320 static_cast<int>(
header.msgType), ret);
327 packet = std::make_shared<EthPacketData>(
header.dataPacketLength);
329 panic_if(!ret,
"Error while reading socket");
330 packet->simLength =
header.simLength;
331 packet->length =
header.dataPacketLength;