kstm-su / ictsc_2020_kstm

0 stars 0 forks source link

何かがおかしい。。。。 #7

Closed ritsuxis closed 3 years ago

ritsuxis commented 3 years ago

問題文

R1にて自作のルーティングアプリケーションをGolangで作成してみました。 しかし、自作アプリケーションのミスでそれぞれのHostにpingを飛ばしても、パケットロスを起こしてしまう。

image

この問題を解決してほしい。 注意点:R1のルーティングアプリケーションは初期実行されていないので注意が必要です。 ーー起動方法ーー

cd ~/go/src/github.com/yoneyan/ictsc-ace/cmd/routing go get . go build . sudo ./routing start eth1 eth2 eth3 eth4

にてルーティングアプリケーションを起動することができます。

また、ソースコードは https://drive.google.com/file/d/1njTGorOGDsI1yUYpZlMj0bFLBlbukjX4/view?usp=sharing にて公開しています。

前提条件

kernelパラメーターの変更をしてはならない

初期状態

それぞれのHostにpingを飛ばしても、パケットロスを起こしてしまう。 (pingができる時と出来ないときがある。)

終了状態

それぞれのHostにpingを飛ばして、パケットロスが起こらない状態にしてほしい。

koba1t commented 3 years ago

tcpdumpで見た所、icmpはちゃんとルーテイングされているが、icmp replyがルータからicmpの送信元ホストに送られてない。

koba1t commented 3 years ago

packetの送信に使う、グローバルなチャンネルpacketsがnic間で共有されているため、 各nic用のreceiver関数内で、自らのmacアドレスかそうでないかを判定して、違う場合は何もしないという処理を行っていた。

そのため送信acketが偶然該当のnicのchanに送らてた場合のみpacketが外部に送信されるという状況だった。

解決策として、もしnicが違った場合は外部に送信せずにチャンネルpacketsに再送信する処理を行うことでパケットの消失が大幅に減った。

        for {
            msg := <-packets
            fmt.Println("get sending packet" + msg.Interface)
            if msg.Interface == mac.String() {
                err := handle.WritePacketData(msg.Packets)
                if err != nil {
                    log.Println(err)
                }
            } else {
                packets <- msg
            }

        }

言い訳: 時間がなかった............

koba1t commented 3 years ago

PoC

package main

import (
    "fmt"
    "strconv"
)

var msgChan = make(chan string)

func f(id int) {
    for {
        msg := <-msgChan
        fmt.Printf("{id: %d, msg: %s}\n", id, msg)
    }
}

func main() {
    fmt.Println("start")

    for i := 0; i < 4; i++ {
        go f(i)
    }

    cnt := 0
    for {
        msgChan <- "{counter: " + strconv.Itoa(cnt) + "}"
        cnt += 1
    }
}