1
0
Fork 0

Improve connection handling

next
Ambrose Chua 2018-03-01 20:21:05 +08:00
parent ae64d58e60
commit 3c4dd9ff2b
2 changed files with 62 additions and 36 deletions

98
main.go
View File

@ -13,68 +13,94 @@ var connect string
func main() { func main() {
flag.IntVar(&key, "key", 170, "key to xor the data") flag.IntVar(&key, "key", 170, "key to xor the data")
flag.StringVar(&listen, "listen", ":8000", "listen on ip and port") flag.StringVar(&listen, "listen", ":8081", "listen on ip and port")
flag.StringVar(&connect, "connect", "", "forward to ip and port") flag.StringVar(&connect, "connect", ":8080", "forward to ip and port")
flag.Parse() flag.Parse()
if key < 0 || key > 255 { if key < 0 || key > 255 {
flag.PrintDefaults() flag.PrintDefaults()
log.Fatal("key is not one byte") log.Fatal("key is not one byte")
} }
if len(connect) < 3 { // check and parse address
flag.PrintDefaults() conn, err := net.ResolveTCPAddr("tcp", connect)
log.Fatal("no connection specified") if err != nil {
} flag.PrintDefaults()
log.Fatal(err)
}
// listen on address
ln, err := net.Listen("tcp", listen) ln, err := net.Listen("tcp", listen)
if err != nil { if err != nil {
flag.PrintDefaults() flag.PrintDefaults()
log.Fatal(err) log.Fatal(err)
} }
log.Print("listening on " + listen)
log.Print("will connect to " + connect)
for { log.Printf("listening on %v", ln.Addr())
log.Printf("will connect to %v", conn)
for i := 0; ; i++ {
// accept new connection
c, err := ln.Accept() c, err := ln.Accept()
if err != nil { if err != nil {
log.Print(err) log.Fatal(err)
continue }
}
log.Print("Connection from "+c.RemoteAddr().String())
cn, err := net.Dial("tcp", connect) log.Printf("connection %v from %v", i, c.RemoteAddr())
cn, err := net.DialTCP("tcp", nil, conn)
if err != nil { if err != nil {
c.Close()
log.Print(err) log.Print(err)
continue continue
} }
go pipe(c, cn, byte(key)) go pipe(c, cn, byte(key), i)
go pipe(cn, c, byte(key)) go pipe(cn, c, byte(key), i)
} }
} }
func pipe(w io.WriteCloser, r io.ReadCloser, key byte) { func pipe(w io.WriteCloser, r io.ReadCloser, key byte, count int) {
buff := make([]byte, 65535) n, err := copyBufferXor(w, r, key)
r.Close()
w.Close()
log.Printf("connection %v closed, %v bytes", count, n)
opError, ok := err.(*net.OpError)
if err != nil && (!ok || opError.Op != "readfrom") {
log.Printf("warning! %v", err)
}
}
func copyBufferXor(dst io.Writer, src io.Reader, key byte) (written int64, err error) {
buf := make([]byte, 32*1024)
for { for {
n, rerr := r.Read(buff) nr, er := src.Read(buf)
for i := 0; i < n; i++ { for i := 0; i < nr; i++ {
buff[i] = buff[i] ^ key buf[i] = buf[i] ^ key
} }
wn, werr := w.Write(buff[:n]) if nr > 0 {
if n != wn { nw, ew := dst.Write(buf[0:nr])
log.Print("mismatch") if nw > 0 {
} written += int64(nw)
}
if werr != nil { if ew != nil {
r.Close() err = ew
log.Print(werr) break
return }
if nr != nw {
err = io.ErrShortWrite
break
}
} }
if rerr != nil { if er != nil {
w.Close() if er != io.EOF {
log.Print(rerr) err = er
return }
break
} }
} }
return written, err
} }

BIN
scramble

Binary file not shown.