You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
2.4 KiB
Go

package main
import (
"io"
"net"
"net/url"
log "github.com/fangdingjun/go-log/v5"
"github.com/gorilla/websocket"
)
func forwardWS2WS(conn1, conn2 *websocket.Conn) {
ch := make(chan struct{}, 2)
go func() {
for {
t, data, err := conn1.ReadMessage()
if err != nil {
log.Errorln(err)
break
}
err = conn2.WriteMessage(t, data)
if err != nil {
log.Errorln(err)
break
}
}
ch <- struct{}{}
}()
go func() {
for {
t, data, err := conn2.ReadMessage()
if err != nil {
log.Errorln(err)
break
}
err = conn1.WriteMessage(t, data)
if err != nil {
log.Errorln(err)
break
}
}
ch <- struct{}{}
}()
<-ch
}
func forwardWS2TCP(conn1 *websocket.Conn, conn2 net.Conn) {
ch := make(chan struct{}, 2)
go func() {
for {
_, data, err := conn1.ReadMessage()
if err != nil {
log.Errorln(err)
break
}
_, err = conn2.Write(data)
if err != nil {
log.Errorln(err)
break
}
}
ch <- struct{}{}
}()
go func() {
buf := make([]byte, 1024)
for {
n, err := conn2.Read(buf)
if err != nil {
if err != io.EOF {
log.Errorln(err)
}
break
}
err = conn1.WriteMessage(websocket.BinaryMessage, buf[:n])
if err != nil {
log.Errorln(err)
break
}
}
ch <- struct{}{}
}()
<-ch
}
func forwardTCP2TCP(c1, c2 net.Conn) {
ch := make(chan struct{}, 2)
go func() {
_, err := io.Copy(c1, c2)
if err != nil {
log.Errorln(err)
}
ch <- struct{}{}
}()
go func() {
_, err := io.Copy(c2, c1)
if err != nil {
log.Errorln(err)
}
ch <- struct{}{}
}()
<-ch
}
func makeServers(cfg conf) {
var wsservers = []wsServer{}
var tcpservers = []tcpServer{}
for _, c := range cfg.ProxyConfig {
u, err := url.Parse(c.Listen)
if err != nil {
log.Fatalf("parse %s, error %s", c.Listen, err)
}
switch u.Scheme {
case "ws":
exists := false
for i := 0; i < len(wsservers); i++ {
if wsservers[i].addr == u.Host {
exists = true
wsservers[i].rule = append(wsservers[i].rule, forwardRule{u.Path, c.Remote})
break
}
}
if !exists {
wsservers = append(wsservers, wsServer{u.Host, []forwardRule{{u.Path, c.Remote}}})
}
case "tcp":
tcpservers = append(tcpservers, tcpServer{u.Host, c.Remote})
default:
log.Fatalf("unsupported scheme %s", u.Scheme)
}
}
for _, srv := range wsservers {
go srv.run()
}
for _, srv := range tcpservers {
go srv.run()
}
}