64 lines
894 B
Go
64 lines
894 B
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"log"
|
||
|
"net"
|
||
|
)
|
||
|
|
||
|
type Server struct {
|
||
|
Addr string
|
||
|
Target string
|
||
|
}
|
||
|
|
||
|
func (s *Server) ListenAndServe() error {
|
||
|
listener, err := net.Listen("tcp", s.Addr)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return s.serve(listener)
|
||
|
}
|
||
|
|
||
|
func (s *Server) serve(ln net.Listener) error {
|
||
|
for {
|
||
|
conn, err := ln.Accept()
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
continue
|
||
|
}
|
||
|
go s.handleConn(conn)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *Server) handleConn(conn net.Conn) {
|
||
|
rconn, err := net.Dial("tcp", s.Target)
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
var pipe = func(src, dst net.Conn) {
|
||
|
defer func() {
|
||
|
conn.Close()
|
||
|
rconn.Close()
|
||
|
}()
|
||
|
|
||
|
buff := make([]byte, 65535)
|
||
|
for {
|
||
|
n, err := src.Read(buff)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return
|
||
|
}
|
||
|
b := buff[:n]
|
||
|
|
||
|
_, err = dst.Write(b)
|
||
|
if err != nil {
|
||
|
log.Println(err)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
go pipe(conn, rconn)
|
||
|
go pipe(rconn, conn)
|
||
|
}
|