in client.go [574:623]
func tcpProbe(test *ethrTest, hop int, hopIP string, hopData *ethrHopData) (error, bool) {
isLast := false
c, err := IcmpNewConn(test.remoteIP)
if err != nil {
ui.printErr("Failed to create ICMP connection. Error: %v", err)
return err, isLast
}
defer c.Close()
localPortNum := uint16(8888)
if gClientPort != 0 {
localPortNum = gClientPort
}
localPortNum += uint16(hop)
b := make([]byte, 4)
binary.BigEndian.PutUint16(b[0:], localPortNum)
remotePortNum, err := strconv.ParseUint(test.remotePort, 10, 16)
binary.BigEndian.PutUint16(b[2:], uint16(remotePortNum))
peerAddrChan := make(chan string)
endTimeChan := make(chan time.Time)
go func() {
peerAddr, _, _ := icmpRecvMsg(c, TCP, time.Second*2, hopIP, b, nil, 0)
endTimeChan <- time.Now()
peerAddrChan <- peerAddr
}()
startTime := time.Now()
conn, err := ethrDialEx(TCP, test.dialAddr, gLocalIP, localPortNum, hop, int(gTOS))
if err != nil {
ui.printDbg("Failed to Dial the connection. Error: %v", err)
} else {
conn.Close()
}
hopData.sent++
peerAddr := ""
endTime := time.Now()
if err == nil {
isLast = true
peerAddr = test.remoteIP
} else {
endTime = <-endTimeChan
peerAddr = <-peerAddrChan
}
elapsed := endTime.Sub(startTime)
if peerAddr == "" || (hopIP != "" && peerAddr != hopIP) {
hopData.lost++
ui.printDbg("Neither connection completed, nor ICMP TTL exceeded received.")
return os.ErrNotExist, isLast
}
genHopData(hopData, peerAddr, elapsed)
return nil, isLast
}