Exemplo n.º 1
0
func (netservice *NetService) NewTcpTask(conn *net.TCPConn) {
	fmt.Println(conn.RemoteAddr())
	fmt.Println(conn.LocalAddr())
	/*
		go func (conn *net.TCPConn) {
			readdata := make([]byte,1000)

			for true {
				_,err := conn.Read(readdata)
				if err == nil {
					fmt.Println("========",readdata)
					msg := &MsgDefine.BaseMsg{}
					proto.Unmarshal(readdata[4:],msg)
					basemsg := msg.String()
					fmt.Println("basemsg",basemsg)
					fmt.Printf("%s===\n",basemsg)
				} else {
						fmt.Println("close================ error")
						conn.Close()
						break
					}
			}

		}(conn)
	*/
}
Exemplo n.º 2
0
func newRCConn(c *net.TCPConn, iface *Interface) (*RCConn, error) {
	// Leave enough room in the completion queue for any operation,
	// including inline sends, to return an error. CQ overruns
	// sometimes cause internal errors in the HCA, which can make the
	// kernel very unhappy.
	qp, err := iface.NewQueuePair(10)
	if err != nil {
		return nil, err
	}

	if err := c.SetDeadline(ioDeadline()); err != nil {
		checkClose(qp)
		return nil, err
	}
	destLid, destQpn, destPsn, err := writeReadQPParams(c, iface.Lid(), qp.Qpn(), qp.Psn())
	if err != nil {
		checkClose(qp)
		return nil, err
	}

	messages, meta := CreateBuffers()

	if err := qp.Setup(destLid, destQpn, destPsn, messages); err != nil {
		checkClose(qp)
		return nil, err
	}

	laddr, raddr := c.LocalAddr(), c.RemoteAddr()

	rcc := &RCConn{iface, laddr, raddr, qp, math.MaxInt64, true, messages, meta, false}
	return rcc, nil
}
Exemplo n.º 3
0
func copyBytes(in, out *net.TCPConn) {
	glog.Infof("Copying from %v <-> %v <-> %v <-> %v",
		in.RemoteAddr(), in.LocalAddr(), out.LocalAddr(), out.RemoteAddr())
	if _, err := io.Copy(in, out); err != nil {
		glog.Errorf("I/O error: %v", err)
	}
	in.CloseRead()
	out.CloseWrite()
}
Exemplo n.º 4
0
// proxyTCP proxies data bi-directionally between in and out.
func proxyTCP(in, out *net.TCPConn) {
	var wg sync.WaitGroup
	wg.Add(2)
	glog.V(4).Infof("Creating proxy between %v <-> %v <-> %v <-> %v",
		in.RemoteAddr(), in.LocalAddr(), out.LocalAddr(), out.RemoteAddr())
	go copyBytes("from backend", in, out, &wg)
	go copyBytes("to backend", out, in, &wg)
	wg.Wait()
}
Exemplo n.º 5
0
// GetOriginalDST retrieves the original destination address from
// NATed connection.  Currently, only Linux iptables using DNAT/REDIRECT
// is supported.  For other operating systems, this will just return
// conn.LocalAddr().
//
// Note that this function only works when nf_conntrack_ipv4 and/or
// nf_conntrack_ipv6 is loaded in the kernel.
func GetOriginalDST(conn *net.TCPConn) (*net.TCPAddr, error) {
	f, err := conn.File()
	if err != nil {
		return nil, err
	}
	defer f.Close()

	fd := int(f.Fd())
	// revert to non-blocking mode.
	// see http://stackoverflow.com/a/28968431/1493661
	if err = syscall.SetNonblock(fd, true); err != nil {
		return nil, os.NewSyscallError("setnonblock", err)
	}

	v6 := conn.LocalAddr().(*net.TCPAddr).IP.To4() == nil
	if v6 {
		var addr syscall.RawSockaddrInet6
		var len uint32
		len = uint32(unsafe.Sizeof(addr))
		err = getsockopt(fd, syscall.IPPROTO_IPV6, IP6T_SO_ORIGINAL_DST,
			unsafe.Pointer(&addr), &len)
		if err != nil {
			return nil, os.NewSyscallError("getsockopt", err)
		}
		ip := make([]byte, 16)
		for i, b := range addr.Addr {
			ip[i] = b
		}
		pb := *(*[2]byte)(unsafe.Pointer(&addr.Port))
		return &net.TCPAddr{
			IP:   ip,
			Port: int(pb[0])*256 + int(pb[1]),
		}, nil
	}

	// IPv4
	var addr syscall.RawSockaddrInet4
	var len uint32
	len = uint32(unsafe.Sizeof(addr))
	err = getsockopt(fd, syscall.IPPROTO_IP, SO_ORIGINAL_DST,
		unsafe.Pointer(&addr), &len)
	if err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	ip := make([]byte, 4)
	for i, b := range addr.Addr {
		ip[i] = b
	}
	pb := *(*[2]byte)(unsafe.Pointer(&addr.Port))
	return &net.TCPAddr{
		IP:   ip,
		Port: int(pb[0])*256 + int(pb[1]),
	}, nil
}
Exemplo n.º 6
0
// proxyTCP proxies data bi-directionally between in and out.
func proxyTCP(in, out *net.TCPConn) {
	var wg sync.WaitGroup
	wg.Add(2)
	glog.Infof("Creating proxy between %v <-> %v <-> %v <-> %v",
		in.RemoteAddr(), in.LocalAddr(), out.LocalAddr(), out.RemoteAddr())
	go copyBytes(in, out, &wg)
	go copyBytes(out, in, &wg)
	wg.Wait()
	in.Close()
	out.Close()
}
Exemplo n.º 7
0
func CopyBytes(in, out *net.TCPConn) {
	log.Printf("Copying from %v <-> %v <-> %v <-> %v",
		in.RemoteAddr(), in.LocalAddr(), out.LocalAddr(), out.RemoteAddr())
	_, err := io.Copy(in, out)
	if err != nil && err != io.EOF {
		log.Printf("I/O error: %v", err)
	}

	in.CloseRead()
	out.CloseWrite()
}
Exemplo n.º 8
0
func NewClient(conn *net.TCPConn) *Client {
	client := new(Client)
	client.conn = conn
	client.wt = make(chan *Message, 10)
	addr := conn.LocalAddr()
	if taddr, ok := addr.(*net.TCPAddr); ok {
		ip4 := taddr.IP.To4()
		client.public_ip = int32(ip4[0])<<24 | int32(ip4[1])<<16 | int32(ip4[2])<<8 | int32(ip4[3])
	}
	return client
}
Exemplo n.º 9
0
func (s *Server) handleConnection(c *net.TCPConn) {
	defer c.Close()

	var addr string

	switch s.config.Mode {
	case ModeNAT:
		orig_addr, err := GetOriginalDST(c)
		if err != nil {
			log.Error(err.Error(), nil)
			return
		}
		addr = orig_addr.String()
	default:
		addr = c.LocalAddr().String()
	}

	if log.Enabled(log.LvDebug) {
		log.Debug("making proxy connection", map[string]interface{}{
			"_dst": addr,
		})
	}

	pconn, err := s.dialer.Dial("tcp", addr)
	if err != nil {
		log.Error(err.Error(), map[string]interface{}{
			"_dst": addr,
		})
		return
	}
	defer pconn.Close()

	ch := make(chan error, 2)
	go copyData(c, pconn, ch)
	go copyData(pconn, c, ch)
	for i := 0; i < 2; i++ {
		e := <-ch
		if e != nil {
			log.Error(e.Error(), map[string]interface{}{
				"_dst": addr,
			})
			break
		}
	}

	if log.Enabled(log.LvDebug) {
		log.Debug("closing proxy connection", map[string]interface{}{
			"_dst": addr,
		})
	}
}
Exemplo n.º 10
0
func StartGateway(conn *net.TCPConn) {

	logger.Logf("new client: %s->%s\n",
		conn.RemoteAddr(),
		conn.LocalAddr())

	ircConn := NewIRCConn(conn, SERVERNAME)
	lilyConn := NewLilyConn(LILYADDRESS)

	dis := NewDispatcher(ircConn, lilyConn)
	dis.Dispatch()

	logger.Log("ending session")
}
Exemplo n.º 11
0
// proxyTCP proxies data bi-directionally between in and out.
func proxyTCP(logLevel int, in, out *net.TCPConn) {
	var wg sync.WaitGroup
	wg.Add(2)

	if logLevel > 0 {
		log.Printf("Creating proxy between %v <-> %v <-> %v <-> %v",
			in.RemoteAddr(), in.LocalAddr(), out.LocalAddr(), out.RemoteAddr())
	}

	go copyBytes(logLevel, "from backend", in, out, &wg)
	go copyBytes(logLevel, "to backend", out, in, &wg)
	wg.Wait()
	in.Close()
	out.Close()
}
Exemplo n.º 12
0
func newTunnel(conn *net.TCPConn, rc4key []byte) *Tunnel {
	desc := fmt.Sprintf("tunnel[%s <-> %s]", conn.LocalAddr(), conn.RemoteAddr())
	bufsize := int(PacketSize) * 2
	tunnel := &Tunnel{
		writer: bufio.NewWriterSize(NewRC4Writer(conn, rc4key), bufsize),
		reader: bufio.NewReaderSize(NewRC4Reader(conn, rc4key), bufsize),
		wch:    make(chan Payload),
		closed: make(chan struct{}),
		conn:   conn,
		desc:   desc,
	}

	go tunnel.pump()
	return tunnel
}
Exemplo n.º 13
0
Arquivo: tcp.go Projeto: dulumao/goim
func serveTCP(server *Server, conn *net.TCPConn, r int) {
	var (
		// timer
		tr = server.round.Timer(r)
		rp = server.round.Reader(r)
		wp = server.round.Writer(r)
		// ip addr
		lAddr = conn.LocalAddr().String()
		rAddr = conn.RemoteAddr().String()
	)
	if Debug {
		log.Debug("start tcp serve \"%s\" with \"%s\"", lAddr, rAddr)
	}
	server.serveTCP(conn, rp, wp, tr)
}
Exemplo n.º 14
0
func newTunnel(conn *net.TCPConn) *Tunnel {
	conn.SetKeepAlive(true)
	conn.SetKeepAlivePeriod(time.Second * 60)
	conn.SetLinger(-1)
	// conn.SetWriteBuffer(64 * 1024)
	// conn.SetReadBuffer(64 * 1024)
	desc := fmt.Sprintf("tunnel[%s <-> %s]", conn.LocalAddr(), conn.RemoteAddr())
	return &Tunnel{
		wlock:  new(sync.Mutex),
		writer: NewRC4Writer(conn, options.RC4Key),
		rlock:  new(sync.Mutex),
		reader: NewRC4Reader(bufio.NewReaderSize(conn, 8192), options.RC4Key),
		conn:   conn,
		desc:   desc,
	}
}
Exemplo n.º 15
0
func (p *Proxy) proxyTCPStream(ctx context.Context, src *net.TCPConn) {
	srcRemoteAddr := src.RemoteAddr().(*net.TCPAddr)
	srcLocalAddr := src.LocalAddr().(*net.TCPAddr)

	route := p.routes.GetTable().Lookup(protocols.TCP,
		srcRemoteAddr.IP, srcLocalAddr.IP,
		uint16(srcRemoteAddr.Port), uint16(srcLocalAddr.Port))
	if route == nil {
		src.Close()
		return
	}

	go func() {
		dstAddr := net.TCPAddr{
			IP:   route.Outbound.DstIP,
			Port: int(route.Outbound.DstPort),
		}

		dst, err := net.DialTCP("tcp", nil, &dstAddr)
		if err != nil {
			src.Close()
			return
		}

		dst.SetKeepAlivePeriod(10 * time.Second)
		src.SetKeepAlivePeriod(10 * time.Second)

		go func() {
			<-ctx.Done()
			src.Close()
			dst.Close()
		}()

		go func() {
			defer dst.CloseWrite()
			defer src.CloseRead()
			io.Copy(dst, src)
		}()

		go func() {
			defer src.CloseWrite()
			defer dst.CloseRead()
			io.Copy(src, dst)
		}()
	}()
}
Exemplo n.º 16
0
func (self *TunnelServer) handleConn(conn *net.TCPConn) {
	defer self.wg.Done()
	defer conn.Close()
	defer Recover()

	Info("create tunnel: %v <-> %v", conn.LocalAddr(), conn.RemoteAddr())
	hub := newServerHub(newTunnel(conn))
	self.addHub(hub)
	defer self.removeHub(hub)

	err := hub.Start()
	if err != nil {
		Error("hub start failed:%s", err.Error())
		return
	}
	hub.Wait()
}
Exemplo n.º 17
0
func serveTCP(server *Server, conn *net.TCPConn, r int) {
	var (
		// bufpool
		rrp = server.round.Reader(r) // reader
		wrp = server.round.Writer(r) // writer
		// timer
		tr = server.round.Timer(r)
		// buf
		rr = NewBufioReaderSize(rrp, conn, Conf.ReadBufSize)  // reader buf
		wr = NewBufioWriterSize(wrp, conn, Conf.WriteBufSize) // writer buf
		// ip addr
		lAddr = conn.LocalAddr().String()
		rAddr = conn.RemoteAddr().String()
	)
	log.Debug("start tcp serve \"%s\" with \"%s\"", lAddr, rAddr)
	server.serveTCP(conn, rrp, wrp, rr, wr, tr)
}
Exemplo n.º 18
0
//远程调试信息
func handleRemoteConn(tcpConn *net.TCPConn) {
	if tcpConn == nil {
		return
	}
	addConnection(tcpConn)
	utils.Info("received remote debug client:%s", tcpConn.LocalAddr().String())
	tcpConn.Write([]byte("welcome to debug service...."))
	for {
		_, err := tcpConn.Read(buff)
		if err == io.EOF {
			utils.Info("remote disconnect:%s", tcpConn.RemoteAddr().String())
			removeConnection(tcpConn)
			tcpConn.Close()
			return
		}
	}
}
Exemplo n.º 19
0
func (this *Server) login(conn *net.TCPConn) (msgs.CometType, error) {
	buf := make([]byte, 1)
	n, err := conn.Read(buf)
	if err != nil || n != 1 {
		return 0, fmt.Errorf("Read info error [%s]<-[%s] [%s]\n", conn.LocalAddr(), conn.RemoteAddr(), err.Error())
	}
	switch msgs.CometType(buf[0]) {
	case msgs.CometWs:
	case msgs.CometUdp:
	default:
		return 0, fmt.Errorf("wrong CometType %v", buf[0])
	}
	_, err = conn.Write(buf)
	if err != nil {
		return 0, fmt.Errorf("Send ack error [%s]->[%s] [%s]\n", conn.LocalAddr(), conn.RemoteAddr(), err.Error())
	}
	return msgs.CometType(buf[0]), nil
}
Exemplo n.º 20
0
func serveTCP(server *Server, conn *net.TCPConn, r int) {
	var (
		// bufpool
		rp = server.round.Reader(r) // reader
		wp = server.round.Writer(r) // writer
		// bufio
		rr = NewBufioReaderSize(rp, conn, Conf.ReadBufSize)  // reader buf
		wr = NewBufioWriterSize(wp, conn, Conf.WriteBufSize) // writer buf
		fr = wr                                              // flusher
		cr = conn
		// ip addr
		lAddr = conn.LocalAddr().String()
		rAddr = conn.RemoteAddr().String()
	)
	log.Debug("start serve \"%s\" with \"%s\"", lAddr, rAddr)
	server.serve(rr, wr, fr, cr, r)
	PutBufioReader(rp, rr)
	PutBufioWriter(wp, wr)
}
Exemplo n.º 21
0
func (self *BackServer) handleClient(conn *net.TCPConn) {
	defer conn.Close()

	// try skip tgw
	err := skipTGW(conn)
	if err != nil {
		Error("skip tgw failed, source: %v", conn.RemoteAddr())
		return
	}

	Info("create tunnel: %v <-> %v", conn.LocalAddr(), conn.RemoteAddr())
	tunnel := NewTunnel(conn)
	frontDoor := NewFrontServer(tunnel)
	err = frontDoor.Start()
	if err != nil {
		Error("frontDoor start failed:%s", err.Error())
		return
	}
	frontDoor.Wait()
}
Exemplo n.º 22
0
func telnetHandler(c *net.TCPConn) {
	defer c.Close()
	fmt.Printf("Connection from %s to %s established.\n", c.RemoteAddr(), c.LocalAddr())
	io.WriteString(c, fmt.Sprintf("Welcome on %s\n", c.LocalAddr()))
	buf := make([]byte, 4096)
	for {
		n, err := c.Read(buf)
		if (err != nil) || (n == 0) {
			c.Close()
			break
		}
		str := strings.TrimSpace(string(buf[0:n]))
		hub.messages <- str
		io.WriteString(c, "sent to "+strconv.Itoa(len(hub.clients))+" clients\n")
	}
	time.Sleep(150 * time.Millisecond)
	fmt.Printf("Connection from %v closed.\n", c.RemoteAddr())
	c.Close()
	return
}
Exemplo n.º 23
0
// Handle handles new incomming connection
func (p *Proxy) Handle(inCon *net.TCPConn, num int64) {
	const buffer = 32
	defer func() {
		inCon.Close()
		atomic.AddInt64(&p.counter, -1)
	}()
	outCon, err := p.Dial()
	if err != nil {
		p.LogInfo.Printf("handle connection error: %v\n", err)
		return
	}
	defer outCon.Close()
	end := make(chan string)
	fromServer, fromClient := make([]byte, buffer), make([]byte, buffer)
	p.LogDebug.Printf("session [%v]: %v-%v <-> %v-%v\n", num,
		inCon.LocalAddr(), inCon.RemoteAddr(),
		outCon.LocalAddr(), outCon.RemoteAddr())
	// client (incCon) <- proxy <- server (outCon)
	transmission := func(in, out *net.TCPConn, b []byte, name string) {
		defer func() {
			end <- name
		}()
		for {
			n, err := in.Read(b)
			if err != nil {
				p.LogDebug.Printf("can't read data [%s]: %v", name, err)
				return
			}
			n, err = out.Write(b[:n])
			if err != nil {
				p.LogDebug.Printf("can't write data [%s]: %v", name, err)
				return
			}
		}
	}
	// server -> client
	go transmission(outCon, inCon, fromServer, "server")
	// client -> server
	go transmission(inCon, outCon, fromClient, "client")
	p.LogDebug.Printf("finish session[%v] [initiator=%v]\n", num, <-end)
}
Exemplo n.º 24
0
func handletcp(conn *net.TCPConn) {
	fmt.Printf("TCP connection from %s (to %s)... ",
		conn.RemoteAddr(), conn.LocalAddr())
	total := 0
	for {
		message := make([]byte, chunkTCPsize)
		n1, err := conn.Read(message)
		if err != nil {
			if err == io.EOF {
				break
			}
			panic("Cannot read")
		}
		n2, err := conn.Write(message[0:n1])
		checkError("Cannot write", err)
		if n2 != n1 {
			panic("Cannot write completely")
		}
		total += n2
	}
	fmt.Printf("Echoed %d bytes\n", total)
	conn.Close()
}
Exemplo n.º 25
0
//本地调试信息
func handleLocalConn(tcpConn *net.TCPConn) {
	if tcpConn == nil {
		return
	}
	var v *net.TCPConn
	var ll int
	var err error
	utils.Info("received local debug client:%s", tcpConn.LocalAddr().String())
	for {
		ll, err = tcpConn.Read(rcvbuffer)
		if err == io.EOF {
			tcpConn.Close()
			return
		} else {
			con.rw.RLock()
			for _, v = range con.conlist {
				v.Write(rcvbuffer[0:ll])
			}
			con.rw.RUnlock()
		}
	}
	tcpConn.Close()
}
Exemplo n.º 26
0
func (self *Server) handleConn(conn *net.TCPConn) {
	defer self.wg.Done()
	defer conn.Close()
	defer Recover()

	Info("create tunnel: %v <-> %v", conn.LocalAddr(), conn.RemoteAddr())

	// authenticate connection
	a := NewTaa(self.app.Secret)
	a.GenToken()

	challenge := a.GenCipherBlock(nil)
	Debug("challenge(%v), len %d, %v", conn.RemoteAddr(), len(challenge), challenge)
	if _, err := conn.Write(challenge); err != nil {
		Error("write challenge failed(%v):%s", conn.RemoteAddr(), err)
		return
	}

	token := make([]byte, TaaBlockSize)
	if _, err := io.ReadFull(conn, token); err != nil {
		Error("read token failed(%v):%s", conn.RemoteAddr(), err)
		return
	}

	Debug("token(%v), len %d, %v", conn.RemoteAddr(), len(token), token)
	if !a.VerifyCipherBlock(token) {
		Error("verify token failed(%v)", conn.RemoteAddr())
		return
	}

	tunnel := newTunnel(conn, a.GetRc4key())
	hub := newServerHub(tunnel, self.app)
	self.addHub(hub)
	defer self.removeHub(hub)

	hub.Start()
}
Exemplo n.º 27
0
// Forward the incoming TCP connection to one of the remote addresses
func forward(backend *Backend, local *net.TCPConn, remote *net.TCPConn) {
	var wg sync.WaitGroup
	wg.Add(2)
	logDebug("<%s> Start transfer %s to %s", remote.RemoteAddr(), local.LocalAddr(), remote.LocalAddr())
	go copy_half(backend, local, remote, &wg)
	go copy_half(backend, remote, local, &wg)
	wg.Wait()
	logDebug("<%s> Finished transfer from %s to %s done", remote.RemoteAddr(), local.LocalAddr(), remote.LocalAddr())
}
Exemplo n.º 28
0
func (self *TunnelServer) handleClient(conn *net.TCPConn) {
	defer conn.Close()
	defer self.wg.Done()

	// try skip tgw
	err := skipTGW(conn)
	if err != nil {
		Error("skip tgw failed, source: %v", conn.RemoteAddr())
		return
	}

	Info("create tunnel: %v <-> %v", conn.LocalAddr(), conn.RemoteAddr())
	tunnel := NewTunnel(conn)
	door := self.newDoor(tunnel)
	self.addDoor(door)
	defer self.removeDoor(door)

	err = door.Start()
	if err != nil {
		Error("door start failed:%s", err.Error())
		return
	}
	door.Wait()
}
Exemplo n.º 29
0
func (r *PacketReader) Listen(conn *net.TCPConn) {

	for _, connection := range r.connections {
		if connection == conn {
			utils.Debug("PacketReader: Already listening on Connection", conn, ". Skipped enabling another listener.")
			return
		}
	}
	r.connections = append(r.connections, conn)

	utils.Debug("PacketReader: Now listening on Connection:", conn)
	r.recovering[conn] = []byte{}
	defer conn.Close()
LoopListen:
	for r.master.IsValidConnection(conn) {
		select {
		case <-r.quit:
			utils.Debug("PacketReader: LoopListen stopped. (Quit)", conn)
			break LoopListen
		default:
			if len(r.recovering[conn]) > 0 {
				r.Recover(conn)
				if !r.master.IsValidConnection(conn) {
					utils.Debug("PacketReader: LoopListen stopped. (Recovering failed)", conn)
					r.master.deadConnections <- conn
					break LoopListen
				}
			} else {
				packet, err := r.Read(conn)
				if err != nil {
					netOpError, ok := err.(*net.OpError)
					if err == io.EOF || err.Error()[0:11] == "WSARecv tcp" || (ok && netOpError.Err.Error() == "read: connection reset by peer") {
						r.master.SetValidConnection(conn, false)
						r.master.deadConnections <- conn
						utils.Debug("PacketReader: LoopListen stopped. (Client disconnected)", conn)
						break LoopListen
					}
					if ok && netOpError.Err.Error() == "use of closed network connection" {
						r.master.SetValidConnection(conn, false)
						r.master.deadConnections <- conn
						utils.Debug("PacketReader: LoopListen stopped. (Lost Connection)", conn)
						break LoopListen
					}
					utils.Debug("PacketReader: Error reading a packet for Connection", conn, ":", err)
					continue
				}
				if config.DEBUG {
					utils.Debug(conn.RemoteAddr(), "->", conn.LocalAddr(), "Len:", packet.ContentLength, "Packet:", packet)
				} else {
					utils.Print(conn.RemoteAddr(), "->", conn.LocalAddr(), "Len:", packet.ContentLength)
				}
				r.master.NewMessage(packet)
			}
		}
	}
	for index, connection := range r.connections {
		if connection == conn {
			r.connections = append(r.connections[:index], r.connections[index+1:]...)
			break
		}
	}
	delete(r.recovering, conn)
	utils.Debug("PacketReader stopped listening on Connection:", conn)
}
Exemplo n.º 30
0
// proxyTCP proxies data bi-directionally between in and out.
func proxyTCP(in, out *net.TCPConn) {
	glog.Infof("Creating proxy between %v <-> %v <-> %v <-> %v",
		in.RemoteAddr(), in.LocalAddr(), out.LocalAddr(), out.RemoteAddr())
	go copyBytes(in, out)
	go copyBytes(out, in)
}