Reputation: 71
I have CentOS on my server and the server has two NIC.
I want to capture any packets on NIC number 1 and forward them to NIC number 2. I use Socket in my C++ application to capture and froward the packets, then I use IPerf to analyze my application. so I connect each of the NICs to different computers (Computer A and B) and try to send UDP packets from computer A to B. The server suppose to capture packets from A then forward them to B and vice versa.
It works well when I'm pinging computer B from A, but there are some things wrong when I try to generate more packets via IPerf. IPerf generate 100K UDP packets per second (22 bytes payload) and send it from A to B, but computer B does not receive all of the packets in a same time! for example if IPerf on A send 100K packets at the first second, Computer B receive these packets at 20 seconds! It seems like some caching system on server that holds the received packet! let me just show you what happened:
[OS: CentOS]
[00:00] Computer A Start Sending...
[00:01] Computer A send 100,000 packets
[00:01] Finnish
[00:00] Computer B start to listen...
[00:01] Computer B receive 300 packets
[00:02] Computer B receive 250 packets
[00:03] Computer B receive 200 packets
[00:04] Computer B receive 190 packets
[00:05] Computer B receive 180 packets
[00:06] Computer B receive 170 packets
[00:07] Computer B receive 180 packets
[00:08] Computer B receive 20 packets
[00:09] Computer B receive 3 packets
[00:10] (same things happened until all 100K packets will receive, it takes long time)
At the 4th second, I unplugged the network cable from computer A to make sure it's not sending any packets any more, after that computer B is still receiving packets! It seems like something holds the traffic at the server and releases it slowly. I tried to turn the firewall off but nothing has been changed.
I changed the server OS and use Ubuntu to check if there is any problem in my code, but it works well on Ubuntu. after that I tried to change CentOS sockets buffer size but it doesn't help. here is some of important part of my code:
How I setup a socket:
int packet_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (packet_socket == -1) {
printf("Can't create AF_PACKET socket\n");
return -1;
}
// We would use V3 because it could read/pool in per block basis instead per packet
int version = TPACKET_V3;
int setsockopt_packet_version = setsockopt(packet_socket, SOL_PACKET, PACKET_VERSION, &version, sizeof(version));
if (setsockopt_packet_version < 0) {
printf("Can't set packet v3 version\n");
return -1;
}
//Set Interface in Promiscuous Mode
struct ifreq ifopts;
strncpy(ifopts.ifr_name,interface_name,IFNAMSIZ-1);
ioctl(packet_socket,SIOCGIFFLAGS,&ifopts);
ifopts.ifr_flags|=IFF_PROMISC;
ioctl(packet_socket,SIOCGIFFLAGS,&ifopts);
//Bind Socket On Specific Interface
struct sockaddr_ll sockll;
bzero((char *)&sockll,sizeof(sockll));
sockll.sll_family=AF_PACKET;
sockll.sll_protocol=htons(ETH_P_ALL);
sockll.sll_ifindex=get_interface_index(interface_name,packet_socket);
bind(packet_socket,(struct sockaddr *) &sockll , sizeof(sockll));
And here I receive packets:
u_char *packet;
packet=new u_char[1600];
*length = recv(packet_socket ,packet,1600,0);
And here I send packets:
int res = write(packet_socket ,packet,PacketSize);
I'm so confused and I don't know what is going on CentOS. Can you please help me to understand what is happening?
Is CentOS a good choice for doing this job?
Thank you.
Upvotes: 0
Views: 390