私は自分のサーバーにCentOSを持っており、サーバーには2つのNICがあります。
NIC番号1のパケットをキャプチャしてNIC番号2に転送したいと思います。私はC++アプリケーションでSocketを使用してパケットをキャプチャし、frowardした後、IPerfを使用してアプリケーションを分析します。私はNICをそれぞれ別のコンピュータ(コンピュータAとB)に接続し、コンピュータAからBへUDPパケットを送信しようとします。サーバはAからのパケットをキャプチャしてBに転送し、その逆も同様です。
AからコンピュータBにpingしているときにうまく動作しますが、IPerf経由でさらに多くのパケットを生成しようとするといくつかの問題があります。 IPerfは1秒間に100K UDPパケット(22バイトのペイロード)を生成し、それをAからBに送信しますが、コンピュータBは同じ時間にすべてのパケットを受信しません。たとえば、AのIPerfが最初の秒に100Kパケットを送信した場合、コンピュータBは20秒でこれらのパケットを受信します。受信したパケットを保持するサーバ上のキャッシングシステムのようです!そのコンピュータBがある後4秒でCentosはUbuntuと同様にパケットを受信しません - ソケットを使用してください
[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)
を、私は、それはそれ以上の任意のパケットを送信していないことを確認するために、コンピュータAからネットワークケーブルを抜い:私はちょうどあなたが何が起こったかを示してみましょうまだパケットを受信しています!何かがサーバー上のトラフィックを保持し、それをゆっくりと解放するようです。私はファイアウォールをオフにしようとしましたが、何も変更されていません。
私は、サーバーOSを変更し、私のコードに問題がないかどうかを確認するためにUbuntuを使用しましたが、Ubuntuではうまくいきます。その後、CentOSソケットのバッファサイズを変更しようとしましたが、それは役に立ちません。私はパケットを受信
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));
そしてここに:どのようにセットアップソケット
:
u_char *packet;
packet=new u_char[1600];
*length = recv(packet_socket ,packet,1600,0);
そして、ここで私は、パケットを送信します。
int res = write(packet_socket ,packet,PacketSize);
ここに私のコードの重要な部分の一部であります
私はとても混乱しており、CentOSで何が起こっているのか分かりません。何が起こっているのか理解してもらえますか?
CentOSはこの仕事をするのに適していますか?
ありがとうございます。