diff --git a/cmd/netstack/main.go b/cmd/netstack/main.go index 7916e60..d037da8 100644 --- a/cmd/netstack/main.go +++ b/cmd/netstack/main.go @@ -184,10 +184,17 @@ func (conn *UdpConn) Read(rcv []byte) (int, error) { } } -func (conn *UdpConn) Write(snd []byte) { - _, _, err := conn.ep.Write(tcpip.SlicePayload(snd), tcpip.WriteOptions{To: &conn.raddr}) - if err != nil { - log.Fatal(err) +func (conn *UdpConn) Write(snd []byte) error { + for { + _, notifyCh, err := conn.ep.Write(tcpip.SlicePayload(snd), tcpip.WriteOptions{To: &conn.raddr}) + if err != nil { + if err == tcpip.ErrNoLinkAddress { + <-notifyCh + continue + } + return fmt.Errorf("%s", err.String()) + } + return nil } } diff --git a/tcpip/network/arp/arp.go b/tcpip/network/arp/arp.go index d4f6111..011dcd6 100644 --- a/tcpip/network/arp/arp.go +++ b/tcpip/network/arp/arp.go @@ -151,7 +151,7 @@ func (*protocol) LinkAddressRequest(addr, localAddr tcpip.Address, linkEP stack. copy(h.HardwareAddressSender(), linkEP.LinkAddress()) copy(h.ProtocolAddressSender(), localAddr) copy(h.ProtocolAddressTarget(), addr) - + log.Println("arp发起广播 寻找:", addr) return linkEP.WritePacket(r, hdr, buffer.VectorisedView{}, ProtocolNumber) } diff --git a/tcpip/stack/linkaddrcache.go b/tcpip/stack/linkaddrcache.go index 5393c55..05b80d4 100644 --- a/tcpip/stack/linkaddrcache.go +++ b/tcpip/stack/linkaddrcache.go @@ -201,7 +201,8 @@ func (c *linkAddrCache) makeAndAddEntry(k tcpip.FullAddress, v tcpip.LinkAddress } // get reports any known link address for k. -func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error) { +func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, + localAddr tcpip.Address, linkEP LinkEndpoint, waker *sleep.Waker) (tcpip.LinkAddress, <-chan struct{}, *tcpip.Error) { log.Println("在arp本地缓存中寻找", k) if linkRes != nil { if addr, ok := linkRes.ResolveStaticAddress(k.Addr); ok { @@ -214,7 +215,7 @@ func (c *linkAddrCache) get(k tcpip.FullAddress, linkRes LinkAddressResolver, lo // 尝试从缓存中得到MAC地址 if entry, ok := c.cache[k]; ok { switch s := entry.state(); s { - case expired: + case expired: // 过期了 case ready: return entry.linkAddr, nil, nil case failed: @@ -251,7 +252,8 @@ func (c *linkAddrCache) removeWaker(k tcpip.FullAddress, waker *sleep.Waker) { } } -func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes LinkAddressResolver, localAddr tcpip.Address, linkEP LinkEndpoint, done <-chan struct{}) { +func (c *linkAddrCache) startAddressResolution(k tcpip.FullAddress, linkRes LinkAddressResolver, + localAddr tcpip.Address, linkEP LinkEndpoint, done <-chan struct{}) { for i := 0; ; i++ { // Send link request, then wait for the timeout limit and check // whether the request succeeded. diff --git a/tcpip/stack/stack.go b/tcpip/stack/stack.go index b27b530..c20f211 100644 --- a/tcpip/stack/stack.go +++ b/tcpip/stack/stack.go @@ -13,7 +13,8 @@ import ( const ( // ageLimit is set to the same cache stale time used in Linux. - ageLimit = 1 * time.Minute + //ageLimit = 1 * time.Minute + ageLimit = 5 * time.Second // resolutionTimeout is set to the same ARP timeout used in Linux. resolutionTimeout = 1 * time.Second // resolutionAttempts is set to the same ARP retries used in Linux.