Пример #1
0
// 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
}
Пример #2
0
func tcpServe(localConf *utils.LocalConf) {
	nl, err := net.Listen("tcp", fmt.Sprintf("%s:%d", localConf.Address, localConf.Port))
	if err != nil {
		utils.Fatalf("Create server error %s", err)
	}
	defer nl.Close()

	utils.Infof("Client listen on %s://%s:%d", localConf.Protocol, localConf.Address, localConf.Port)

	var handleFunc func(c protocols.Protocol)
	switch localConf.Protocol {
	case "http":
		handleFunc = handleHTTP
	case "socks5":
		handleFunc = handleSocks5
	}

	for {
		c, err := nl.Accept()
		if err != nil {
			utils.Errorf("Local connection accept error %s", err)
			continue
		}
		utils.Infof("Get local connection from %s", c.RemoteAddr())
		go handleFunc(c)
	}

}
Пример #3
0
// Serve handles connection between socks5 client and remote addr.
func (s *TCPRelay) Serve() (err error) {
	defer func() {
		if !s.closed {
			s.conn.Close()
		}
	}()
	s.handShake()

	cmd, rawAddr, addr, err := s.parseRequest()
	if err != nil {
		utils.Errorf("Parse request error %v\n", err)
		return
	}

	utils.Infof("Proxy connection to %s\n", string(addr))
	s.reply()

	switch cmd {
	case CONNECT:
		s.connect(rawAddr)
	case UDP_ASSOCIATE:
		s.udpAssociate()
	case BIND:
	default:
		err = fmt.Errorf("unknow cmd type")
	}

	return
}
Пример #4
0
func (c *Mika) Read(b []byte) (n int, err error) {
	// recover() avoid panic
	var buf = c.readBuf
	// dataLen := len(b)
	if c.serverSide {
		// ------------------------------
		// | dataLen | hmac | user data |
		// ------------------------------
		// |   2     | 10   | Variable  |
		// ------------------------------
		const datePos = 12
		if _, err := io.ReadFull(c.Conn, buf[:datePos]); err != nil {
			return 0, err
		}

		dataLen := int(binary.BigEndian.Uint16(buf[:2]))
		expectedhmac := make([]byte, 10)
		copy(expectedhmac, buf[2:datePos])

		utils.Debugf("dataLen %d expected len %d", dataLen, len(b))

		if dataLen > len(b) {
			utils.Errorf("Date len %d large than b %d", dataLen, len(b))
			return 0, fmt.Errorf("Too large data")
		}

		if _, err := io.ReadFull(c.Conn, b[:dataLen]); err != nil {
			utils.Errorf("Read error %s", err)
			return 0, err
		}

		c.header.ChunkID++
		utils.Debugf("ChunkID %d, receive %d datas, expectedhmac %#v ", c.header.ChunkID, dataLen, expectedhmac)

		_, hmac := otaReqChunkAuth(c.iv, c.header.ChunkID, b[:dataLen])
		if !bytes.Equal(hmac, expectedhmac) {
			utils.Errorf("Hmac %#v mismatch with %#v, remote addr %s", hmac, expectedhmac, c.RemoteAddr())
			return 0, fmt.Errorf("Hmac mismatch")
		}
		// if dataLen > b
		// we should buffer remains.
		return dataLen, nil
	}

	return c.Conn.Read(b)
}
Пример #5
0
func handle(c protocols.Protocol, cg *mika.CryptoGenerator) {
	mikaConn, err := mika.NewMika(c, cg.NewCrypto(), nil)
	if err != nil {
		c.Close()
		utils.Errorf("Create mika connection error %s", err)
		return
	}
	mika.Serve(mikaConn)
}
Пример #6
0
// 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
}
Пример #7
0
func listen(serverInfo *utils.ServerConf) {
	nl, err := net.Listen("tcp", fmt.Sprintf("%s:%d", serverInfo.Address, serverInfo.Port))
	if err != nil {
		utils.Fatalf("Create server error %s", err)
	}

	utils.Infof("Listen on %d\n", serverInfo.Port)
	cg := mika.NewCryptoGenerator(serverInfo.Method, serverInfo.Password)

	for {
		c, err := nl.Accept()
		if err != nil {
			utils.Errorf("Accept connection error %s", err)
			continue
		}

		go func() {
			tcpConn := &tcp.Conn{c, time.Duration(serverInfo.Timeout) * time.Second}
			handle(tcpConn, cg)
		}()
	}
}