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
82 unsigned dist_rank,
unsigned dist_size,
86 DistIface(dist_rank, dist_size, sync_start, sync_repeat,
em, use_pseudo_op,
87 is_switch, num_nodes), serverName(server_name),
88 serverPort(server_port), isSwitch(is_switch), listening(false)
92 DPRINTF(DistEthernet,
"TCPIface(listen): Can't bind port %d\n",
103 for (
int i = 0;
i <
size;
i++) {
105 DPRINTF(DistEthernet,
"First connection, waiting for link info\n");
107 panic(
"Failed to receive link info");
117 panic(
"Socket already listening!");
119 struct sockaddr_in sockaddr;
122 fdStatic = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
125 sockaddr.sin_family = PF_INET;
126 sockaddr.sin_addr.s_addr = INADDR_ANY;
127 sockaddr.sin_port = htons(port);
129 memset(&sockaddr.sin_zero, 0,
sizeof(sockaddr.sin_zero));
130 ret = ::bind(
fdStatic, (
struct sockaddr *)&sockaddr,
sizeof (sockaddr));
133 if (ret == -1 && errno != EADDRINUSE)
134 panic(
"ListenSocket(listen): bind() failed!");
139 if (errno != EADDRINUSE)
140 panic(
"ListenSocket(listen): listen() failed!");
153 static unsigned cur_rank = 0;
154 static unsigned cur_id = 0;
162 return cn.first.rank == cur_rank;
164 assert(iface0 !=
nodes.end());
165 assert(iface0->first.distIfaceId == 0);
166 sock = iface0->second;
170 DPRINTF(DistEthernet,
"Next connection, waiting for link info\n");
172 panic(
"Failed to receive link info");
173 assert(
ni.rank == cur_rank);
174 assert(
ni.distIfaceId == cur_id);
176 inform(
"Link okay (iface:%d -> (node:%d, iface:%d))",
178 if (
ni.distIfaceId <
ni.distIfaceNum - 1) {
195 DPRINTF(DistEthernet,
"Connected, waiting for ack (distIfaceId:%d\n",
198 panic(
"Failed to receive ack");
209 struct sockaddr_in sockaddr;
210 socklen_t slen =
sizeof (sockaddr);
214 if (setsockopt(
sock, IPPROTO_TCP, TCP_NODELAY, (
char *)&
i,
216 warn(
"ListenSocket(accept): setsockopt() TCP_NODELAY failed!");
223 struct addrinfo addr_hint, *addr_results;
228 sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
229 panic_if(
sock < 0,
"socket() failed: %s", strerror(errno));
232 if (setsockopt(
sock, IPPROTO_TCP, TCP_NODELAY, (
char *)&fl,
sizeof(fl)) < 0)
233 warn(
"ConnectSocket(connect): setsockopt() TCP_NODELAY failed!");
235 bzero(&addr_hint,
sizeof(addr_hint));
236 addr_hint.ai_family = AF_INET;
237 addr_hint.ai_socktype = SOCK_STREAM;
238 addr_hint.ai_protocol = IPPROTO_TCP;
240 ret = getaddrinfo(
serverName.c_str(), port_str.c_str(),
241 &addr_hint, &addr_results);
242 panic_if(ret < 0,
"getaddrinf() failed: %s", strerror(errno));
244 DPRINTF(DistEthernet,
"Connecting to %s:%s\n",
247 ret =
::connect(
sock, (
struct sockaddr *)(addr_results->ai_addr),
248 addr_results->ai_addrlen);
249 panic_if(ret < 0,
"connect() failed: %s", strerror(errno));
251 freeaddrinfo(addr_results);
267 ret = ::send(
sock, buf,
length, MSG_NOSIGNAL);
269 if (errno == ECONNRESET || errno == EPIPE) {
270 exitSimLoop(
"Message server closed connection, simulation "
273 panic(
"send() failed: %s", strerror(errno));
284 ret = ::recv(
sock, buf,
length, MSG_WAITALL );
286 if (errno == ECONNRESET || errno == EPIPE)
287 inform(
"recv(): %s", strerror(errno));
289 panic(
"recv() failed: %s", strerror(errno));
290 }
else if (ret == 0) {
291 inform(
"recv(): Connection closed");
293 panic(
"recv() failed");
308 DPRINTF(DistEthernetCmd,
"TCPIface::sendCmd() type: %d\n",
309 static_cast<int>(
header.msgType));
321 DPRINTF(DistEthernetCmd,
"TCPIface::recvHeader() type: %d ret: %d\n",
322 static_cast<int>(
header.msgType), ret);
329 packet = make_shared<EthPacketData>(
header.dataPacketLength);
331 panic_if(!ret,
"Error while reading socket");
332 packet->simLength =
header.simLength;
333 packet->length =
header.dataPacketLength;