reality/cmd/grsu/main.go
2024-10-10 11:08:23 +08:00

113 lines
2.3 KiB
Go

package main
import (
"context"
"errors"
"flag"
"io"
"net"
"time"
"github.com/hashicorp/yamux"
"github.com/howmp/reality"
"github.com/howmp/reality/cmd"
"github.com/sirupsen/logrus"
)
type serverSession struct {
config *reality.ClientConfig
session *yamux.Session
logger logrus.FieldLogger
}
func newServerSession(config *reality.ClientConfig, logger logrus.FieldLogger) *serverSession {
return &serverSession{
config: config,
logger: logger,
}
}
func (s *serverSession) connectForever() {
for {
s.connect()
s.logger.Infoln("sleep 5s")
time.Sleep(time.Second * 5)
}
}
func (s *serverSession) connect() {
logger := s.logger
client, err := reality.NewClient(context.Background(), s.config, cmd.OverlayGRSU)
if err != nil {
logger.Errorf("connect server: %v", err)
return
}
defer client.Close()
session, err := yamux.Server(client, nil)
if err != nil {
logger.Errorf("yamux: %v", err)
return
}
defer session.Close()
s.session = session
logger.Infof("session opened %s", client.RemoteAddr())
<-session.CloseChan()
logger.Infof("session closed %s", client.RemoteAddr())
}
func (s *serverSession) openSessionStream() (*yamux.Stream, error) {
if s.session != nil {
stream, err := s.session.OpenStream()
if err != nil {
s.session.Close()
s.session = nil
return nil, err
}
return stream, nil
}
return nil, errors.New("session not open")
}
func main() {
config, err := reality.UnmarshalClientConfig(cmd.ConfigDataPlaceholder)
if err != nil {
println(err.Error())
return
}
addr := flag.String("l", "127.0.0.1:61080", "socks5 listen address")
flag.Parse()
logger := reality.GetLogger(config.Debug)
l, err := net.Listen("tcp", *addr)
if err != nil {
logger.Panic(err)
}
logger.Infof("listen %s", *addr)
s := newServerSession(config, logger)
go s.connectForever()
for {
conn, err := l.Accept()
if err != nil {
logger.Errorf("accept: %v", err)
continue
}
go handleUser(conn, s, logger)
}
}
func handleUser(conn net.Conn, s *serverSession, logger logrus.FieldLogger) {
defer conn.Close()
stream, err := s.openSessionStream()
if err != nil {
logger.Errorf("open session stream: %v", err)
return
}
defer stream.Close()
go io.Copy(stream, conn)
io.Copy(conn, stream)
}