106 lines
1.6 KiB
Go
106 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"log"
|
|
"crypto/tls"
|
|
"net"
|
|
)
|
|
|
|
const localAddr string = ":25500"
|
|
const remoteAddr string = "127.0.0.1:25501"
|
|
const MaxConn int16 = 3
|
|
|
|
func main() {
|
|
log.SetFlags(log.Lshortfile)
|
|
|
|
cer, err := tls.LoadX509KeyPair("server.pem", "server.key")
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
|
|
config := &tls.Config{Certificates: []tls.Certificate{cer}}
|
|
ln, err := tls.Listen("tcp", localAddr, config)
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
defer ln.Close()
|
|
|
|
log.Printf("Listening: %v -> %v\n\n", localAddr, remoteAddr)
|
|
|
|
for {
|
|
conn, err := ln.Accept()
|
|
if err != nil {
|
|
log.Println(err)
|
|
continue
|
|
}
|
|
go proxyConn(conn)
|
|
}
|
|
}
|
|
|
|
func proxyConn(conn net.Conn) {
|
|
defer conn.Close()
|
|
|
|
rAddr, err := net.ResolveTCPAddr("tcp", remoteAddr)
|
|
if err != nil {
|
|
log.Print(err)
|
|
}
|
|
|
|
rConn, err := net.DialTCP("tcp", nil, rAddr)
|
|
if err != nil {
|
|
log.Print(err)
|
|
}
|
|
defer rConn.Close()
|
|
|
|
Pipe(conn, rConn)
|
|
|
|
log.Printf("handleConnection end: %s\n", conn.RemoteAddr())
|
|
}
|
|
|
|
func chanFromConn(conn net.Conn) chan []byte {
|
|
c := make(chan []byte)
|
|
|
|
go func() {
|
|
b := make([]byte, 1024)
|
|
|
|
for {
|
|
n, err := conn.Read(b)
|
|
if n > 0 {
|
|
res := make([]byte, n)
|
|
// Copy the buffer so it doesn't get changed while read by the recipient.
|
|
copy(res, b[:n])
|
|
c <- res
|
|
}
|
|
if err != nil {
|
|
c <- nil
|
|
break
|
|
}
|
|
}
|
|
}()
|
|
|
|
return c
|
|
}
|
|
|
|
func Pipe(conn1 net.Conn, conn2 net.Conn) {
|
|
chan1 := chanFromConn(conn1)
|
|
chan2 := chanFromConn(conn2)
|
|
|
|
for {
|
|
select {
|
|
case b1 := <-chan1:
|
|
if b1 == nil {
|
|
return
|
|
} else {
|
|
conn2.Write(b1)
|
|
}
|
|
case b2 := <-chan2:
|
|
if b2 == nil {
|
|
return
|
|
} else {
|
|
conn1.Write(b2)
|
|
}
|
|
}
|
|
}
|
|
}
|