diff options
| author | Mistivia <i@mistivia.com> | 2025-11-02 15:29:28 +0800 |
|---|---|---|
| committer | Mistivia <i@mistivia.com> | 2025-11-02 15:29:28 +0800 |
| commit | 9f42c2d5f911cb4e215d7873221e642ce7df4d61 (patch) | |
| tree | 6dac90a889a7402a9556d3d1bcc5cb53cdb9f123 /webircgateway/pkg/proxy | |
| parent | fb2d9de539b660a261af19b1cbcceb7ee7980cb1 (diff) | |
deprecate webircdateway and ngircd
Diffstat (limited to 'webircgateway/pkg/proxy')
| -rw-r--r-- | webircgateway/pkg/proxy/proxy.go | 129 | ||||
| -rw-r--r-- | webircgateway/pkg/proxy/server.go | 237 |
2 files changed, 0 insertions, 366 deletions
diff --git a/webircgateway/pkg/proxy/proxy.go b/webircgateway/pkg/proxy/proxy.go deleted file mode 100644 index c332f40..0000000 --- a/webircgateway/pkg/proxy/proxy.go +++ /dev/null @@ -1,129 +0,0 @@ -package proxy - -import ( - "encoding/json" - "errors" - "io" - "net" -) - -type KiwiProxyState int - -const KiwiProxyStateClosed KiwiProxyState = 0 -const KiwiProxyStateConnecting KiwiProxyState = 1 -const KiwiProxyStateHandshaking KiwiProxyState = 2 -const KiwiProxyStateConnected KiwiProxyState = 3 - -type ConnError struct { - Msg string - Type string -} - -func (err *ConnError) Error() string { - return err.Msg -} - -type KiwiProxyConnection struct { - Username string - ProxyInterface string - DestHost string - DestPort int - DestTLS bool - State KiwiProxyState - Conn *net.Conn -} - -func MakeKiwiProxyConnection() *KiwiProxyConnection { - return &KiwiProxyConnection{ - State: KiwiProxyStateClosed, - } -} - -func (c *KiwiProxyConnection) Close() error { - if c.State == KiwiProxyStateClosed { - return errors.New("Connection already closed") - } - - return (*c.Conn).Close() -} - -func (c *KiwiProxyConnection) Dial(proxyServerAddr string) error { - if c.State != KiwiProxyStateClosed { - return errors.New("Connection in closed state") - } - - c.State = KiwiProxyStateConnecting - - conn, err := net.Dial("tcp", proxyServerAddr) - if err != nil { - return err - } - - c.Conn = &conn - c.State = KiwiProxyStateHandshaking - - meta, _ := json.Marshal(map[string]interface{}{ - "username": c.Username, - "interface": c.ProxyInterface, - "host": c.DestHost, - "port": c.DestPort, - "ssl": c.DestTLS, - }) - - (*c.Conn).Write(append(meta, byte('\n'))) - - buf := make([]byte, 1024) - bufLen, readErr := (*c.Conn).Read(buf) - if readErr != nil { - (*c.Conn).Close() - c.State = KiwiProxyStateClosed - return readErr - } - - response := string(buf) - if bufLen > 0 && response[0] == '1' { - c.State = KiwiProxyStateConnected - } else { - (*c.Conn).Close() - c.State = KiwiProxyStateClosed - - if bufLen == 0 { - return errors.New("The proxy could not connect to the destination") - } - - switch response[0] { - case '0': - return errors.New("The proxy could not connect to the destination") - case '2': - return &ConnError{Msg: "Connection reset", Type: "conn_reset"} - case '3': - return &ConnError{Msg: "Connection refused", Type: "conn_refused"} - case '4': - return &ConnError{Msg: "Host not found", Type: "not_found"} - case '5': - return &ConnError{Msg: "Connection timed out", Type: "conn_timeout"} - } - } - - return nil -} - -func (c *KiwiProxyConnection) Read(b []byte) (n int, err error) { - if c.State == KiwiProxyStateConnecting || c.State == KiwiProxyStateHandshaking { - return 0, nil - } else if c.State == KiwiProxyStateClosed { - return 0, io.EOF - } else { - return (*c.Conn).Read(b) - } -} - -func (c *KiwiProxyConnection) Write(b []byte) (n int, err error) { - if c.State == KiwiProxyStateConnecting || c.State == KiwiProxyStateHandshaking { - return 0, nil - } else if c.State == KiwiProxyStateClosed { - return 0, io.EOF - } else { - return (*c.Conn).Write(b) - } -} diff --git a/webircgateway/pkg/proxy/server.go b/webircgateway/pkg/proxy/server.go deleted file mode 100644 index 7e3f62f..0000000 --- a/webircgateway/pkg/proxy/server.go +++ /dev/null @@ -1,237 +0,0 @@ -package proxy - -import ( - "bufio" - "crypto/tls" - "encoding/json" - "fmt" - "io" - "log" - "net" - "strconv" - "sync" - "syscall" - "time" - - "github.com/kiwiirc/webircgateway/pkg/identd" -) - -const ( - ResponseError = "0" - ResponseOK = "1" - ResponseReset = "2" - ResponseRefused = "3" - ResponseUnknownHost = "4" - ResponseTimeout = "5" -) - -var identdRpc *identd.RpcClient -var Server net.Listener - -type HandshakeMeta struct { - Host string `json:"host"` - Port int `json:"port"` - TLS bool `json:"ssl"` - Username string `json:"username"` - Interface string `json:"interface"` -} - -func MakeClient(conn net.Conn) *Client { - return &Client{ - Client: conn, - } -} - -type Client struct { - Client net.Conn - Upstream net.Conn - UpstreamAddr *net.TCPAddr - Username string - BindAddr *net.TCPAddr - TLS bool -} - -func (c *Client) Run() { - var err error - - err = c.Handshake() - if err != nil { - log.Println(err.Error()) - return - } - - err = c.ConnectUpstream() - if err != nil { - log.Println(err.Error()) - return - } - - c.Pipe() -} - -func (c *Client) Handshake() error { - // Read the first line - it should be JSON - reader := bufio.NewReader(c.Client) - line, readErr := reader.ReadBytes('\n') - if readErr != nil { - return readErr - } - - var meta = HandshakeMeta{ - Username: "user", - Port: 6667, - Interface: "0.0.0.0", - } - unmarshalErr := json.Unmarshal(line, &meta) - if unmarshalErr != nil { - c.Client.Write([]byte(ResponseError)) - return unmarshalErr - } - - if meta.Host == "" || meta.Port == 0 || meta.Username == "" || meta.Interface == "" { - c.Client.Write([]byte(ResponseError)) - return fmt.Errorf("missing args") - } - - c.Username = meta.Username - c.TLS = meta.TLS - - bindAddr, bindAddrErr := net.ResolveTCPAddr("tcp", meta.Interface+":") - if bindAddrErr != nil { - c.Client.Write([]byte(ResponseError)) - return fmt.Errorf("interface: " + bindAddrErr.Error()) - } - c.BindAddr = bindAddr - - hostStr := net.JoinHostPort(meta.Host, strconv.Itoa(meta.Port)) - addr, addrErr := net.ResolveTCPAddr("tcp", hostStr) - if addrErr != nil { - c.Client.Write([]byte(ResponseUnknownHost)) - return fmt.Errorf("remote host: " + addrErr.Error()) - } - c.UpstreamAddr = addr - - return nil -} - -func (c *Client) ConnectUpstream() error { - dialer := &net.Dialer{} - dialer.LocalAddr = c.BindAddr - dialer.Timeout = time.Second * 10 - - conn, err := dialer.Dial("tcp", c.UpstreamAddr.String()) - if err != nil { - response := "" - errType := typeOfErr(err) - switch errType { - case "timeout": - response = ResponseTimeout - case "unknown_host": - response = ResponseUnknownHost - case "refused": - response = ResponseRefused - } - - c.Client.Write([]byte(response)) - return err - } - - if identdRpc != nil { - lAddr, lPortStr, _ := net.SplitHostPort(conn.LocalAddr().String()) - lPort, _ := strconv.Atoi(lPortStr) - identdRpc.AddIdent(lPort, c.UpstreamAddr.Port, c.Username, lAddr) - } - - if c.TLS { - tlsConfig := &tls.Config{InsecureSkipVerify: true} - tlsConn := tls.Client(conn, tlsConfig) - err := tlsConn.Handshake() - if err != nil { - conn.Close() - c.Client.Write([]byte(ResponseReset)) - return err - } - - conn = net.Conn(tlsConn) - } - - c.Upstream = conn - c.Client.Write([]byte(ResponseOK)) - return nil -} - -func (c *Client) Pipe() { - wg := sync.WaitGroup{} - wg.Add(2) - - go func() { - io.Copy(c.Client, c.Upstream) - c.Client.Close() - wg.Done() - }() - - go func() { - io.Copy(c.Upstream, c.Client) - c.Upstream.Close() - wg.Done() - }() - - wg.Wait() - - if identdRpc != nil { - lAddr, lPortStr, _ := net.SplitHostPort(c.Upstream.LocalAddr().String()) - lPort, _ := strconv.Atoi(lPortStr) - identdRpc.RemoveIdent(lPort, c.UpstreamAddr.Port, c.Username, lAddr) - } -} - -func Start(laddr string) { - srv, err := net.Listen("tcp", laddr) - if err != nil { - log.Fatal(err.Error()) - } - - // Expose the server - Server = srv - log.Printf("Kiwi proxy listening on %s", srv.Addr().String()) - - identdRpc = identd.MakeRpcClient("kiwiproxy" + laddr) - go identdRpc.ConnectAndReconnect("127.0.0.1:1133") - - for { - conn, err := srv.Accept() - if err != nil { - log.Print(err.Error()) - break - } - - c := MakeClient(conn) - go c.Run() - } -} - -func typeOfErr(err error) string { - if err == nil { - return "" - } - - if netError, ok := err.(net.Error); ok && netError.Timeout() { - return "timeout" - } - - switch t := err.(type) { - case *net.OpError: - if t.Op == "dial" { - return "unknown_host" - } else if t.Op == "read" { - return "refused" - } - - case syscall.Errno: - if t == syscall.ECONNREFUSED { - return "refused" - } - } - - return "" -} |
