QTun【step 16最適化パケット損失率】

3105 ワード

一、なぜカバンをなくしたのか
ブロガーが長期にわたって使用した経験から,UDPプロトコルを用いてインターネット上でデータを伝送する際に,一定のパケット損失率が存在する.特に夜の忙しい時間帯では、パケット損失率が明らかになりますが、パケット損失率を低減するにはどのように最適化しますか?
二、どのように解決するか
  • サーバ側はクライアントと同時に検証を行い、一定時間以内にパケット損失が発見された場合、新しいメッセージを送信して相手にメッセージ
  • を再送信ことを通知する.
  • サーバ側とクライアントは、メッセージを送信するたびに、1つのメッセージを複数回
  • に送信する.
    まず、この方法は最も伝統的な方法に属していますが、この方法には欠点があります.ネットワークの状況が非常に悪い場合、送信された要求再送メッセージも失われる可能性があるため、対端は、失われた要求再送のメッセージを再び要求する可能性がある.TCPと同様に、これはネットワーク全体の悪化をもたらす.
    第2のスキームを見てみましょう.各メッセージについて、両端が複数回送信され、理論的には全体的な帯域幅が低下します.ネットワークの状況が悪い場合、1つのメッセージを5回送信したと仮定すると、実際にはこのような偶然の一致はありません.この5回はパケットを失われました.そのため、私はこのスキームに傾いています.実際のテストの過程で、帯域幅は低下していないことがわかりました.逆に、ファイルをダウンロードする速度は以前より安定しています.
    三、どのように実現するか
  • まず最下層の発注関数write_を修正するc
    ssize_t write_c(client_t* client, const void* buf, size_t count) {
        unsigned char i;
        unsigned char successed = 0;
        for (i = 0; i < qtun->multi_send; ++i) {
            if (qtun->use_udp) {
                if (sendto(qtun->remotefd, buf, (int)count, 0, (struct sockaddr*)&client->addr, sizeof(client->addr)) >= 0)
                    ++successed;
            } else {
                const char* ptr = buf;
                size_t left = count;
                while (left) {
                    ssize_t written = write(client->fd, ptr, (unsigned int)left);
                    if (written == 0)
                        return 0;
                    else if (written == -1) {
                        if (errno == EAGAIN || errno == EWOULDBLOCK) continue;
                        return -1;
                    }
                    ptr  += written;
                    left -= written;
                }
                ++successed;
            }
        }
        return count;
    }
    ここではプロファイルのmulti_に基づいてsendパラメータで何回送信するかを決定し、TCPモードでmulti_sendパラメータは常に1
  • msgを定義しますstate_t構造は、各受信メッセージ
    typedef struct {
        unsigned int   ident;
        unsigned short idx;
        unsigned char  used;
    } msg_state_t;
    
  • を保存する.
  • クライアントでt構造ではMSG_を常に記録していますMAX_TTL条受信メッセージid
        msg_state_t        recv_msgs[MSG_MAX_TTL];
    
  • メッセージを受信すると、対応するclient_を優先的にチェックする必要があります.t構造のrecv_msgテーブルにメッセージのシーケンス番号が記録されているかどうか、テーブルにメッセージのシーケンス番号が含まれている場合は、メッセージを
  • に破棄する必要があります.
    四、安全性の強化
    セキュリティを強化するには、qtunの新しいバージョンでは、ローカルエリアネットワーク内で他のホストとの通信がデフォルトで禁止されています.プロファイルでuse_を指定します.local_forwardフラグは、ローカルエリアネットワーク内の通信を開始します.具体的な実装方法は、server_プロセス関数では、パケットのソースアドレスと宛先アドレスが現在のローカルエリアネットワーク内であるかどうかをチェックし、いずれも現在のローカルエリアネットワーク内のパケットであれば、直接パケット損失を行う
                if (!qtun->use_local_forward &&
                    check_ip_by_mask(ipHdr->saddr, qtun->localip, qtun->netmask) &&
                    check_ip_by_mask(ipHdr->daddr, qtun->localip, qtun->netmask)) {
                    return;
                }
    

    五、完全なコード
    完全なコードはstep16に表示されます.
    バージョン番号:1.1.0
    日付:2015-06-13