(destIP netip.Addr, peer tailcfg.NodeView, res *ipnstate.PingResult, cb func(*ipnstate.PingResult))
| 1388 | } |
| 1389 | |
| 1390 | func (e *userspaceEngine) sendICMPEchoRequest(destIP netip.Addr, peer tailcfg.NodeView, res *ipnstate.PingResult, cb func(*ipnstate.PingResult)) { |
| 1391 | srcIP, err := e.mySelfIPMatchingFamily(destIP) |
| 1392 | if err != nil { |
| 1393 | res.Err = err.Error() |
| 1394 | cb(res) |
| 1395 | return |
| 1396 | } |
| 1397 | var icmph packet.Header |
| 1398 | if srcIP.Is4() { |
| 1399 | icmph = packet.ICMP4Header{ |
| 1400 | IP4Header: packet.IP4Header{ |
| 1401 | IPProto: ipproto.ICMPv4, |
| 1402 | Src: srcIP, |
| 1403 | Dst: destIP, |
| 1404 | }, |
| 1405 | Type: packet.ICMP4EchoRequest, |
| 1406 | Code: packet.ICMP4NoCode, |
| 1407 | } |
| 1408 | } else { |
| 1409 | icmph = packet.ICMP6Header{ |
| 1410 | IP6Header: packet.IP6Header{ |
| 1411 | IPProto: ipproto.ICMPv6, |
| 1412 | Src: srcIP, |
| 1413 | Dst: destIP, |
| 1414 | }, |
| 1415 | Type: packet.ICMP6EchoRequest, |
| 1416 | Code: packet.ICMP6NoCode, |
| 1417 | } |
| 1418 | } |
| 1419 | |
| 1420 | idSeq, payload := packet.ICMPEchoPayload(nil) |
| 1421 | |
| 1422 | expireTimer := time.AfterFunc(10*time.Second, func() { |
| 1423 | e.setICMPEchoResponseCallback(idSeq, nil) |
| 1424 | }) |
| 1425 | t0 := time.Now() |
| 1426 | e.setICMPEchoResponseCallback(idSeq, func() { |
| 1427 | expireTimer.Stop() |
| 1428 | d := time.Since(t0) |
| 1429 | res.LatencySeconds = d.Seconds() |
| 1430 | res.NodeIP = destIP.String() |
| 1431 | res.NodeName = peer.ComputedName() |
| 1432 | cb(res) |
| 1433 | }) |
| 1434 | |
| 1435 | icmpPing := packet.Generate(icmph, payload) |
| 1436 | e.tundev.InjectOutbound(icmpPing) |
| 1437 | } |
| 1438 | |
| 1439 | func (e *userspaceEngine) sendTSMPPing(ip netip.Addr, peer tailcfg.NodeView, res *ipnstate.PingResult, cb func(*ipnstate.PingResult)) { |
| 1440 | srcIP, err := e.mySelfIPMatchingFamily(ip) |
no test coverage detected