想将mysql 的TCP 封死,所有外部链接由我的proxy来控制,so 写了一个 tcp 转 unix socket 的 proxy。
package main
import (
"os"
"fmt"
"net"
"io"
"sync"
"time"
)
type proxy struct{
Host string
Port string
Local string
}
func runProxy(list []proxy) {
wg := sync.WaitGroup{}
for _, v := range list {
wg.Add(1)
go func() {
eachServer(v.Host, v.Port, v.Local)
wg.Done()
}()
}
wg.Wait()
}
func eachServer(host string, port string, local string) {
l,err := net.Listen("tcp", fmt.Sprintf("%s:%s", host, port))
if err != nil {
fmt.Print("listen tcp :%s",err.Error())
os.Exit(1)
}
defer l.Close()
for {
tc,err := l.Accept()
if err != nil {
fmt.Printf("accept tcp conn :%s",err.Error())
tc.Close()
continue
}
go eachConn(local, tc)
}
}
func eachConn(local string, tc net.Conn) {
uc,err := net.Dial("unix", local)
if err != nil {
fmt.Printf("get unix conn :%s",err.Error())
uc.Close()
return
}
go io.Copy(tc, uc)
go io.Copy(uc, tc)
}
func main() {
list := []proxy{proxy{Host:"192.168.8.101",Port:"3306",Local:"/home/work/data/tmp/mysql3306.sock"}}
runProxy(list)
}
cat proxy.go
package main
import (
"errors"
"flag"
"log"
"net"
"time"
)
func eachConn(remote string, tc net.Conn) {
uc, err := net.Dial("tcp", remote)
if err != nil {
log.Println("get remote conn :", err.Error())
uc.Close()
return
}
go netCopy(tc, uc)
go netCopy(uc, tc)
}
func netCopy(src, dst net.Conn) error {
buf := make([]byte, 1024)
var err error
for {
nr, err := src.Read(buf)
if err != nil {
break
}
if nr > 0 {
nw, err := dst.Write(buf[0:nr])
if err != nil {
break
} else if nr == nw {
continue
} else if nr != nw {
err = errors.New("short write")
break
}
}
}
return err
}
func main() {
var remote string
var local string
flag.StringVar(&local, "local", ":3114", "local")
flag.StringVar(&remote, "remote", "127.0.0.1:3306", "remote")
help := flag.Bool("help", false, "Display usage")
flag.Parse()
if *help {
flag.PrintDefaults()
return
}
l, err := net.Listen("tcp", local)
if err != nil {
log.Fatalln("listen tcp :", err.Error())
}
defer l.Close()
for {
tc, err := l.Accept()
if err != nil {
log.Println("accept tcp conn :", err.Error())
tc.Close()
continue
}
go eachConn(remote, tc)
}
for {
time.Sleep(time.Minute)
}
}
func init() {
log.SetFlags(log.Lshortfile | log.LstdFlags)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)