mirror of
https://github.com/impact-eintr/netstack.git
synced 2025-10-06 21:32:59 +08:00
fix bug: udp write 提供了对外封装的Write()
表现为一个阻塞操作,如果本地arp缓存失效,就会重新发起一次arp广播,更新目标ip地址的MAC 更新后将再次尝试写数据
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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)
|
||||
}
|
||||
|
||||
|
@@ -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.
|
||||
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user