32 #include <netinet/in.h>
36 #include <sys/socket.h>
37 #include <sys/types.h>
42 #define MAXBUFLEN 5000
44 #define __MF_SUBJECT__ "mfReceiveAndForward"
46 #define __SHORTFILE__ \
47 (__builtin_strstr(&__FILE__[0], "/srcs/") \
48 ? __builtin_strstr(&__FILE__[0], "/srcs/") + 6 \
50 #define __COUT_HDR_L__ "[" << std::dec << __LINE__ << " |\t"
51 #define __COUT_HDR_FL__ __SHORTFILE__ << " " << __COUT_HDR_L__
53 #define __COUT_TYPE__(X) std::cout << QUOTE(X) << ":" << __MF_SUBJECT__ << ":"
54 #define __COUT_ERR__ __COUT_TYPE__(LogError) << __COUT_HDR_FL__
55 #define __COUT_WARN__ __COUT_TYPE__(LogWarning) << __COUT_HDR_FL__
56 #define __COUT_INFO__ __COUT_TYPE__(LogInfo) << __COUT_HDR_FL__
57 #define __COUT__ __COUT_TYPE__(LogDebug) << __COUT_HDR_FL__
60 std::stringstream ss; \
61 ss << "|" << __MF_DECOR__ << ": " << __COUT_HDR_FL__
62 #define __SS_THROW__ \
64 __COUT_ERR__ << "\n" << ss.str(); \
65 throw std::runtime_error(ss.str()); \
67 #define __E__ std::endl
70 #define __COUTV__(X) __COUT__ << QUOTE(X) << " = " << X << __E__
73 void* get_in_addr(
struct sockaddr* sa)
75 if(sa->sa_family == AF_INET)
77 return &(((
struct sockaddr_in*)sa)->sin_addr);
80 return &(((
struct sockaddr_in6*)sa)->sin6_addr);
83 int makeSocket(
const char* ip,
int port,
struct addrinfo*& p)
86 struct addrinfo hints, *servinfo;
90 memset(&hints, 0,
sizeof hints);
91 hints.ai_family = AF_UNSPEC;
92 hints.ai_socktype = SOCK_DGRAM;
94 sprintf(portStr,
"%d", port);
95 if((rv = getaddrinfo(ip, portStr, &hints, &servinfo)) != 0)
97 fprintf(stderr,
"getaddrinfo: %s\n", gai_strerror(rv));
102 for(p = servinfo; p != NULL; p = p->ai_next)
104 if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
106 perror(
"sw: socket");
115 fprintf(stderr,
"sw: failed to create socket\n");
119 freeaddrinfo(servinfo);
124 int main(
int argc,
char** argv)
126 __COUT__ <<
"Starting...\n\n" << __E__;
128 std::string myPort_(
"3000");
129 std::string myFwdPort_(
"3001");
130 std::string myFwdIP_(
"127.0.0.1");
131 std::string enablePrintouts_(
"do not");
134 __COUT__ <<
"port parameter file:" << argv[1] <<
"\n\n" << __E__;
135 FILE* fp = fopen(argv[1],
"r");
139 char tmpParamStr[100];
141 sscanf(tmp,
"%*s %s", tmpParamStr);
142 myPort_ = tmpParamStr;
144 sscanf(tmp,
"%*s %s", tmpParamStr);
145 myFwdPort_ = tmpParamStr;
147 sscanf(tmp,
"%*s %s", tmpParamStr);
148 myFwdIP_ = tmpParamStr;
150 sscanf(tmp,
"%*s %s", tmpParamStr);
151 enablePrintouts_ = tmpParamStr;
155 __COUT__ <<
"port parameter file failed to open: " << argv[1] <<
"\n\n"
158 __COUT__ <<
"Forwarding from: " << myPort_ <<
" to: " << myFwdIP_ <<
":" << myFwdPort_
163 sscanf(myFwdPort_.c_str(),
"%d", &myFwdPort);
165 bool enablePrintouts = enablePrintouts_ ==
"enablePrintouts";
170 struct addrinfo hints, *servinfo, *p;
172 int recvBytes, sentBytes;
173 struct sockaddr_storage their_addr;
174 char buff[MAXBUFLEN * 3];
178 memset(&hints, 0,
sizeof hints);
179 hints.ai_family = AF_UNSPEC;
180 hints.ai_socktype = SOCK_DGRAM;
181 hints.ai_flags = AI_PASSIVE;
183 if((rv = getaddrinfo(NULL, myPort_.c_str(), &hints, &servinfo)) != 0)
185 fprintf(stderr,
"getaddrinfo: %s\n", gai_strerror(rv));
190 for(p = servinfo; p != NULL; p = p->ai_next)
192 if((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1)
194 __COUT__ <<
"listener: socket...\n\n" << __E__;
195 perror(
"listener: socket");
199 if(bind(sockfd, p->ai_addr, p->ai_addrlen) < 0)
202 __COUT__ <<
"listener: bind.\n\n" << __E__;
203 perror(
"listener: bind");
212 __COUT__ <<
"listener: failed to bind socket...\n\n" << __E__;
213 fprintf(stderr,
"listener: failed to bind socket\n");
217 freeaddrinfo(servinfo);
220 unsigned int socketReceiveBufferSize = 0x1400000;
221 if(setsockopt(sockfd,
224 (
char*)&socketReceiveBufferSize,
225 sizeof(socketReceiveBufferSize)) < 0)
226 __COUT_ERR__ <<
"Failed to set socket receive size to 0x" << std::hex
227 << socketReceiveBufferSize << std::dec
228 <<
". Attempting to revert to default." << std::endl;
230 __COUT__ <<
"set socket receive size to 0x" << std::hex << socketReceiveBufferSize
231 << std::dec <<
"." << __E__;
233 int socketLength = 0;
234 socklen_t sizeOfSocketLength =
sizeof(socketLength);
235 if(getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &socketLength, &sizeOfSocketLength) < 0)
236 __COUT_ERR__ <<
"Failed to set socket receive size to 0x" << std::hex
237 << socketReceiveBufferSize << std::dec
238 <<
". Attempting to revert to default." << std::endl;
240 __COUT__ <<
"set socket receive size verified at 0x" << std::hex << socketLength
241 << std::dec <<
"." << __E__;
257 unsigned int pingCounter = 0;
261 fd_set readfds, masterfds;
265 FD_SET(sockfd, &masterfds);
269 int mf_p, mf_i, mf_j;
270 const int MF_POS_OF_ID = 2;
271 const int MF_POS_OF_TYPE = 5;
272 const int MF_POS_OF_MSG = 11;
273 bool firstPartPresent;
274 unsigned int buffi = 0, buffStarti = 0, packCount = 1;
275 char saveChar =
'\0', saveChar2;
277 int mf_labeli, mf_labelsi;
278 unsigned int newSequenceId;
279 unsigned int processId;
281 std::map<unsigned int, unsigned int> sourceLastSequenceID;
286 sendSockfd = makeSocket(myFwdIP_.c_str(), myFwdPort, p);
291 select(sockfd + 1, &readfds, NULL, NULL, &tv);
293 if(FD_ISSET(sockfd, &readfds))
300 addr_len =
sizeof their_addr;
301 if((recvBytes = recvfrom(sockfd,
305 (
struct sockaddr*)&their_addr,
308 __COUT__ <<
"error: recvfrom...\n\n" << __E__;
330 buff[buffi + recvBytes] =
'\0';
345 std::cout <<
"|||" << &buff[buffi] << __E__;
355 for(mf_p = 0, mf_i = 0; mf_i < recvBytes && mf_p < MF_POS_OF_ID; ++mf_i)
356 if(buff[buffi + mf_i] ==
'|')
362 else if(!mf_labeli &&
363 !(buff[buffi + mf_i] >=
'0' && buff[buffi + mf_i] <=
'9'))
365 for(mf_j = mf_i; mf_j < recvBytes; ++mf_j)
366 if(buff[buffi + mf_j] ==
'|')
371 saveChar2 = buff[buffi + mf_labeli];
372 buff[buffi + mf_labeli] =
'\0';
375 saveChar = buff[buffi + mf_j];
376 buff[buffi + mf_j] =
'\0';
378 newSequenceId = atoi(&buff[buffi + mf_i]);
379 processId = atoi(&buff[buffi + mf_labelsi + 1]);
386 sourceLastSequenceID.find(processId) !=
387 sourceLastSequenceID.end() &&
388 ((newSequenceId == 0 && sourceLastSequenceID[processId] !=
391 sourceLastSequenceID[processId] + 1))
394 std::cout <<
"MFfwd missed " << newSequenceId <<
" vs "
395 << sourceLastSequenceID[processId] + 1 <<
" "
396 << (newSequenceId - 1) -
397 (sourceLastSequenceID[processId] + 1) + 1
398 <<
" packet(s) from " << processId <<
"!" << __E__;
407 sourceLastSequenceID[processId] = newSequenceId;
411 buff[buffi + mf_j] = saveChar;
412 buff[buffi + mf_labeli] = saveChar2;
415 if(1 || packCount > 10000)
417 for(mf_p = 0, mf_i = 0; mf_i < recvBytes && mf_p < MF_POS_OF_TYPE; ++mf_i)
418 if(buff[buffi + mf_i] ==
'|')
421 for(mf_j = mf_i; mf_j < recvBytes && mf_p < MF_POS_OF_TYPE + 1; ++mf_j)
422 if(buff[buffi + mf_j] ==
'|')
426 if(mf_i < mf_j && mf_j < recvBytes)
428 saveChar = buff[buffi + mf_j - 1];
429 buff[buffi + mf_j - 1] =
'\0';
431 buff[buffi + mf_j - 1] = saveChar;
437 firstPartPresent =
true;
440 firstPartPresent =
false;
442 for(mf_i = mf_j; mf_i < recvBytes && mf_p < MF_POS_OF_MSG; ++mf_i)
443 if(buff[buffi + mf_i] ==
'|')
446 if(packCount > 10000)
450 std::cout << &buff[buffi + mf_i - 1]
452 else if(firstPartPresent)
460 if(buffi + recvBytes - buffStarti > MAXBUFLEN)
462 __COUT__ <<
"Pack count ==> " << packCount
463 <<
" sz=" << buffi - buffStarti - 1 << __E__;
465 if((sentBytes = sendto(sendSockfd,
467 buffi - buffStarti - 1,
470 p->ai_addrlen)) == -1)
472 __COUT__ <<
"error: sendto...\n\n" << __E__;
473 perror(
"hw: sendto");
480 buffi += recvBytes + 1;
485 if(buffi > MAXBUFLEN * 2)
487 __COUT__ <<
"Wrap Pack count ==> " << packCount
488 <<
" sz=" << buffi - buffStarti - 1 << __E__;
489 if((sentBytes = sendto(sendSockfd,
491 buffi - buffStarti - 1,
494 p->ai_addrlen)) == -1)
496 __COUT__ <<
"error: sendto...\n\n" << __E__;
497 perror(
"hw: sendto");
508 buffi += recvBytes + 1;
512 if(buffi > MAXBUFLEN && packCount > 12)
514 __COUT__ <<
"WrapAvoid Pack count ==> " << packCount
515 <<
" sz=" << buffi - buffStarti - 1 << __E__;
516 if((sentBytes = sendto(sendSockfd,
518 buffi - buffStarti - 1,
521 p->ai_addrlen)) == -1)
523 __COUT__ <<
"error: sendto...\n\n" << __E__;
524 perror(
"hw: sendto");
538 if(++pingCounter > 2 * 60)
542 sendto(sendSockfd, buff, 1, 0, p->ai_addr, p->ai_addrlen)) == -1)
544 __COUT__ <<
"error: ping sendto...\n\n" << __E__;
545 perror(
"hw: ping sendto");
550 else if(pingCounter > 1 && packCount > 1)
553 __COUT__ <<
"Partial Pack count ==> " << packCount - 1
554 <<
" sz=" << buffi - buffStarti - 1 << __E__;
556 if((sentBytes = sendto(sendSockfd,
558 buffi - buffStarti - 1,
561 p->ai_addrlen)) == -1)
563 __COUT__ <<
"error: sendto...\n\n" << __E__;
564 perror(
"hw: sendto");
578 __COUT__ <<
"Exited.\n\n" << __E__;