Files
simple-go-tcp-proxy/tls2tcp_server.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)
}
}
}
}