package main import ( "encoding/hex" "fmt" "io" "log" "net" "sync" ) const ( notice = "ownme.ipredator.se:80" web = "ownme.ipredator.se:443" server = "ownme.ipredator.se:10000" client = "ownme.ipredator.se:10001" // will callback to port 40001 clientRev = "ownme.ipredator.se:10002" ) type Direction string const ( ServerClient Direction = "Server → Client" ClientServer Direction = "Client → Server" ) type Data struct { Round int Dir Direction Data []byte } func dump(dir Direction, src, dst net.Conn, data chan<- Data) error { buf := make([]byte, 4096) r := io.TeeReader(src, dst) for k := 1; ; k++ { n, err := r.Read(buf) if err != nil { if err == io.EOF { return nil } return err } data <- Data{Round: k, Dir: dir, Data: buf[:n]} } } func main() { var wg sync.WaitGroup srv, err := net.Dial("tcp", server) if err != nil { log.Fatal(err) } defer srv.Close() cnt, err := net.Dial("tcp", clientRev) if err != nil { log.Fatal(err) } defer cnt.Close() data := make(chan Data, 1) wg.Add(2) go func() { wg.Wait() close(data) }() go func(dir Direction) { if err := dump(dir, srv, cnt, data); err != nil { log.Println(dir, err) } wg.Done() }(ServerClient) go func(dir Direction) { if err := dump(dir, cnt, srv, data); err != nil { log.Println(dir, err) } wg.Done() }(ClientServer) for d := range data { fmt.Println("#", d.Round, d.Dir, len(d.Data), "bytes") fmt.Println(hex.Dump(d.Data)) } }