// Serve parse data and then send to mika server. func (h *Relay) Serve() { bf := bufio.NewReader(h.conn) req, err := http.ReadRequest(bf) if err != nil { utils.Errorf("Read request error %s", err) return } // TODO Set http protocol flag mikaConn, err := mika.DailWithRawAddrHTTP("tcp", h.ssServer, utils.ToAddr(req.URL.Host), h.cipher) if err != nil { return } defer func() { if !h.closed { err := mikaConn.Close() utils.Errorf("Close connection error %v\n", err) } }() if req.Method == "CONNECT" { _HTTPSHandler(h.conn) } else { _HTTPHandler(mikaConn, req) } go protocols.Pipe(h.conn, mikaConn) protocols.Pipe(mikaConn, h.conn) h.closed = true }
// relay udp data func (s *UDPRelay) relay(rawAddr []byte) (err error) { cg := mika.NewCryptoGenerator("aes-128-cfb", "123456") cipher := cg.NewCrypto() mikaConn, err := mika.DailWithRawAddr("udp", ":8080", rawAddr, cipher) if err != nil { return } defer mikaConn.Close() go protocols.Pipe(s.conn, mikaConn) protocols.Pipe(mikaConn, s.conn) return }
// connect handles CONNECT cmd // Here is a bit magic. It acts as a mika client that redirects conntion to mika server. func (s *TCPRelay) connect(rawAddr []byte) (err error) { // TODO Dail("tcp", rawAdd) would be more reasonable. mikaConn, err := mika.DailWithRawAddr("tcp", s.ssServer, rawAddr, s.cipher) if err != nil { return } defer func() { if !s.closed { err := mikaConn.Close() utils.Errorf("Close connection error %v\n", err) } }() go protocols.Pipe(s.conn, mikaConn) protocols.Pipe(mikaConn, s.conn) s.closed = true return }