gost_software/tcp/server.go
2017-07-18 22:38:09 +08:00

139 lines
2.6 KiB
Go

package tcp
import (
"bufio"
"net"
"net/http"
"github.com/ginuerzh/gosocks4"
"github.com/ginuerzh/gosocks5"
"github.com/ginuerzh/gost"
"github.com/ginuerzh/gost/ssocks"
"github.com/go-log/log"
)
type nodeServer struct {
options *nodeOptions
chain *gost.Chain
}
func (s *nodeServer) Chain() *gost.Chain {
return s.chain
}
func (s *nodeServer) SetChain(chain *gost.Chain) {
s.chain = chain
}
func (s *nodeServer) Options() gost.Options {
return s.options
}
func (s *nodeServer) Run() error {
ln, err := net.Listen("tcp", s.options.BaseOptions().Addr)
if err != nil {
return err
}
defer ln.Close()
for {
conn, err := ln.Accept()
if err != nil {
return err
}
go func(c net.Conn) {
defer c.Close()
s.handleConn(c)
}(conn)
}
}
func (s *nodeServer) handleConn(conn net.Conn) {
switch s.options.BaseOptions().Protocol {
case "ss": // shadowsocks
server, err := ssocks.NewServer(conn, s)
if err != nil {
log.Log("[ss]", err)
}
server.Serve()
return
case "http":
req, err := http.ReadRequest(bufio.NewReader(conn))
if err != nil {
log.Log("[http]", err)
return
}
NewHttpServer(conn, s).HandleRequest(req)
return
case "socks", "socks5":
conn = gosocks5.ServerConn(conn, s.selector)
req, err := gosocks5.ReadRequest(conn)
if err != nil {
log.Log("[socks5]", err)
return
}
NewSocks5Server(conn, s).HandleRequest(req)
return
case "socks4", "socks4a":
req, err := gosocks4.ReadRequest(conn)
if err != nil {
log.Log("[socks4]", err)
return
}
NewSocks4Server(conn, s).HandleRequest(req)
return
}
br := bufio.NewReader(conn)
b, err := br.Peek(1)
if err != nil {
log.Log(err)
return
}
switch b[0] {
case gosocks4.Ver4:
req, err := gosocks4.ReadRequest(br)
if err != nil {
log.Log("[socks4]", err)
return
}
NewSocks4Server(conn, s).HandleRequest(req)
case gosocks5.Ver5:
methods, err := gosocks5.ReadMethods(br)
if err != nil {
log.Log("[socks5]", err)
return
}
method := s.selector.Select(methods...)
if _, err := conn.Write([]byte{gosocks5.Ver5, method}); err != nil {
log.Log("[socks5] select:", err)
return
}
c, err := s.selector.OnSelected(method, conn)
if err != nil {
log.Log("[socks5] onselected:", err)
return
}
conn = c
req, err := gosocks5.ReadRequest(conn)
if err != nil {
log.Log("[socks5] request:", err)
return
}
NewSocks5Server(conn, s).HandleRequest(req)
default: // http
req, err := http.ReadRequest(br)
if err != nil {
log.Log("[http]", err)
return
}
NewHttpServer(conn, s).HandleRequest(req)
}
}