fix bug: udp write 提供了对外封装的Write()

表现为一个阻塞操作,如果本地arp缓存失效,就会重新发起一次arp广播,更新目标ip地址的MAC 更新后将再次尝试写数据
This commit is contained in:
impact-eintr
2022-12-02 21:59:13 +08:00
parent 050d5fec97
commit 2d9434d260
4 changed files with 19 additions and 9 deletions

View File

@@ -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})
func (conn *UdpConn) Write(snd []byte) error {
for {
_, notifyCh, err := conn.ep.Write(tcpip.SlicePayload(snd), tcpip.WriteOptions{To: &conn.raddr})
if err != nil {
log.Fatal(err)
if err == tcpip.ErrNoLinkAddress {
<-notifyCh
continue
}
return fmt.Errorf("%s", err.String())
}
return nil
}
}

View File

@@ -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)
}

View File

@@ -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.

View File

@@ -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.