func (p *Pinger) recvICMP(conn *net.IPConn, recv chan<- *packet, ctx *context, wg *sync.WaitGroup) { p.debugln("recvICMP(): Start") for { select { case <-ctx.stop: p.debugln("recvICMP(): <-ctx.stop") wg.Done() p.debugln("recvICMP(): wg.Done()") return default: } bytes := make([]byte, 512) conn.SetReadDeadline(time.Now().Add(time.Millisecond * 100)) p.debugln("recvICMP(): ReadMsgIP Start") _, _, _, ra, err := conn.ReadMsgIP(bytes, nil) p.debugln("recvICMP(): ReadMsgIP End") if err != nil { if neterr, ok := err.(*net.OpError); ok { if neterr.Timeout() { p.debugln("recvICMP(): Read Timeout") continue } else { p.debugln("recvICMP(): OpError happen", err) p.mu.Lock() ctx.err = err p.mu.Unlock() p.debugln("recvICMP(): close(ctx.done)") close(ctx.done) p.debugln("recvICMP(): wg.Done()") wg.Done() return } } } p.debugln("recvICMP(): p.recv <- packet") select { case recv <- &packet{bytes: bytes, addr: ra}: case <-ctx.stop: p.debugln("recvICMP(): <-ctx.stop") wg.Done() p.debugln("recvICMP(): wg.Done()") return } } }
func readOneICMP4Packet(conn *net.IPConn, deadline time.Time) ( *icmpPacket, error, ) { for { conn.SetReadDeadline(deadline) bytes := make([]byte, 512) _, _, _, ra, err := conn.ReadMsgIP(bytes, nil) if err != nil { if neterr, ok := err.(*net.OpError); ok { if neterr.Timeout() { return nil, err } else { fmt.Println("readOneICMP4Packet(): OpError happen", err) return nil, err } } } fmt.Printf("ICMP: Got packet from %s.\n", ra.String()) return &icmpPacket{bytes: bytes, addr: ra}, nil } }