first commit

This commit is contained in:
2020-02-22 16:49:55 +08:00
parent e9ca570c76
commit 957ea09766
3 changed files with 134 additions and 0 deletions

2
.gitignore vendored
View File

@@ -6,6 +6,8 @@
*.so
*.dylib
simple-tcp-proxy
# Test binary, build with `go test -c`
*.test

124
simple-tcp-proxy.go Normal file
View File

@@ -0,0 +1,124 @@
package main
import (
"fmt"
"io"
"io/ioutil"
"net"
"os"
"strings"
"encoding/json"
)
type TcpListen struct {
Listen string `json:"listen"`
Backend string `json:"backend"`
}
type TcpListenConfig struct {
TcpListens []TcpListen `json:"tcpListens"`
}
// {
// "tcpListens": [
// "listen": ":8080",
// "backend": "11.22.33.44:8080"
// ]
// }
// https://blog.csdn.net/fyxichen/article/details/51505542
func main() {
tcpListenConfig, err := readConfigFile()
if err != nil {
fmt.Printf("Error in load config file: %v\n", err)
return
}
if len(tcpListenConfig.TcpListens) == 0 {
fmt.Println("Not find any mapping in config")
return
}
for _, tcpListen := range tcpListenConfig.TcpListens {
go server(tcpListen)
}
ExitChan := make(chan bool, 1)
<-ExitChan
}
func server(tcpListen TcpListen) {
lis, err := net.Listen("tcp", tcpListen.Listen)
if err != nil {
fmt.Println(err)
return
}
defer lis.Close()
fmt.Printf("Listen TCP at: %v --> %v\n", tcpListen.Listen, tcpListen.Backend)
for {
conn, err := lis.Accept()
if err != nil {
fmt.Printf("Listen error: %v\n", err)
continue
}
fmt.Printf("TCP connection from %v, local: %v\n", conn.RemoteAddr(), conn.LocalAddr())
go handle(tcpListen, conn)
}
}
func handle(tcpListen TcpListen, sconn net.Conn) {
defer sconn.Close()
ip := tcpListen.Backend
dconn, err := net.Dial("tcp", ip)
if err != nil {
fmt.Printf("Connect to %v failed:%v\n", ip, err)
return
}
ExitChan := make(chan bool, 1)
go func(sconn net.Conn, dconn net.Conn, Exit chan bool) {
_, err := io.Copy(dconn, sconn)
if err != nil {
errStr := fmt.Sprintf("%v", err)
if strings.Contains(errStr, "use of closed network connection") {
fmt.Printf("Connection closed: %v\n", ip)
} else {
fmt.Printf("Send data to %v failed:%v\n", ip, err)
}
}
ExitChan <- true
}(sconn, dconn, ExitChan)
go func(sconn net.Conn, dconn net.Conn, Exit chan bool) {
_, err := io.Copy(sconn, dconn)
if err != nil {
errStr := fmt.Sprintf("%v", err)
if strings.Contains(errStr, "use of closed network connection") {
fmt.Printf("Connection closed: %v\n", ip)
} else {
fmt.Printf("Receive data from %v failed:%v\n", ip, err)
}
}
ExitChan <- true
}(sconn, dconn, ExitChan)
<-ExitChan
dconn.Close()
}
func readConfigFile() (*TcpListenConfig, error) {
configFile, err := os.Open("tcp_listen_config.json")
if err != nil {
return nil, err
}
defer configFile.Close()
configFileBytes, err := ioutil.ReadAll(configFile)
if err != nil {
return nil, err
}
var tcpListenConfig TcpListenConfig
err = json.Unmarshal(configFileBytes, &tcpListenConfig)
if err != nil {
return nil, err
}
return &tcpListenConfig, nil
}

8
tcp_listen_config.json Normal file
View File

@@ -0,0 +1,8 @@
{
"tcpListens": [
{
"listen": ":8443",
"backend": "101.132.122.240:443"
}
]
}