dns: code optimize

This commit is contained in:
nadoo 2020-04-13 00:55:11 +08:00
parent ff461f615b
commit 8b43213c76
5 changed files with 27 additions and 47 deletions

View File

@ -17,7 +17,7 @@ we can set up local listeners as proxy servers, and forward requests to internet
## Features
- Act as both proxy client and proxy server
- Flexible proxy & protocol chains
- Multiple forwarders support with the following scheduling algorithm:
- Load balancing with the following scheduling algorithm:
- rr: round robin
- ha: high availability
- lha: latency based high availability
@ -73,7 +73,6 @@ sudo pacman -S glider
## Usage
help:
```bash
glider -h
```
@ -347,7 +346,7 @@ forward=tls://1.1.1.1:443,ws://,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?al
- Chain protocols and servers:
``` bash
forward=socks5://1.1.1.1:1080,tls://2.2.2.2:443,ws://,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2
forward=socks5://1.1.1.1:1080,tls://2.2.2.2:443,vmess://5a146038-0b56-4e95-b1dc-5c6f5a32cd98@?alterID=2
```
- Chain protocols in listener: https proxy server

View File

@ -89,8 +89,22 @@ func (c *Client) Exchange(reqBytes []byte, clientAddr string, preferTCP bool) ([
return respBytes, err
}
ips, ttl := c.extractAnswer(resp)
// add to cache only when there's a valid ip address
if len(ips) != 0 && ttl > 0 {
c.cache.Put(getKey(resp.Question), respBytes, ttl)
}
log.F("[dns] %s <-> %s(%s) via %s, type: %d, %s: %s",
clientAddr, dnsServer, network, dialerAddr, resp.Question.QTYPE, resp.Question.QNAME, strings.Join(ips, ","))
return respBytes, nil
}
func (c *Client) extractAnswer(resp *Message) ([]string, int) {
var ips []string
ttl := c.config.MinTTL
ips := []string{}
for _, answer := range resp.Answers {
if answer.TYPE == QTypeA || answer.TYPE == QTypeAAAA {
for _, h := range c.handlers {
@ -111,15 +125,7 @@ func (c *Client) Exchange(reqBytes []byte, clientAddr string, preferTCP bool) ([
ttl = c.config.MinTTL
}
// add to cache only when there's a valid ip address
if len(ips) != 0 && ttl > 0 {
c.cache.Put(getKey(resp.Question), respBytes, ttl)
}
log.F("[dns] %s <-> %s(%s) via %s, type: %d, %s: %s",
clientAddr, dnsServer, network, dialerAddr, resp.Question.QTYPE, resp.Question.QNAME, strings.Join(ips, ","))
return respBytes, nil
return ips, ttl
}
// exchange choose a upstream dns server based on qname, communicate with it on the network.

View File

@ -24,12 +24,15 @@ type Server struct {
// NewServer returns a new dns server.
func NewServer(addr string, p proxy.Proxy, config *Config) (*Server, error) {
c, err := NewClient(p, config)
if err != nil {
return nil, err
}
s := &Server{
addr: addr,
Client: c,
}
return s, err
return s, nil
}
// Start starts the dns forwarding server.

View File

@ -1,10 +1,3 @@
// https://trojan-gfw.github.io/trojan/protocol
// If the connection is a UDP ASSOCIATE, then each UDP packet has the following format:
// +------+----------+----------+--------+---------+----------+
// | ATYP | DST.ADDR | DST.PORT | Length | CRLF | Payload |
// +------+----------+----------+--------+---------+----------+
// | 1 | Variable | 2 | 2 | X'0D0A' | Variable |
// +------+----------+----------+--------+---------+----------+
package trojan
import (
@ -25,6 +18,7 @@ type PktConn struct {
tgtAddr socks.Addr
}
// NewPktConn returns a PktConn.
func NewPktConn(c net.Conn, tgtAddr socks.Addr) *PktConn {
pc := &PktConn{
Conn: c,
@ -33,6 +27,7 @@ func NewPktConn(c net.Conn, tgtAddr socks.Addr) *PktConn {
return pc
}
// ReadFrom implements the necessary function of net.PacketConn.
func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
// ATYP, DST.ADDR, DST.PORT
_, err := socks.ReadAddr(pc.Conn)
@ -65,6 +60,7 @@ func (pc *PktConn) ReadFrom(b []byte) (int, net.Addr, error) {
return n, nil, err
}
// ReadFrom implements the necessary function of net.PacketConn.
func (pc *PktConn) WriteTo(b []byte, addr net.Addr) (int, error) {
var buf bytes.Buffer
buf.Write(pc.tgtAddr)

View File

@ -1,29 +1,5 @@
// protocol spec:
// https://trojan-gfw.github.io/trojan/protocol
// +-----------------------+---------+----------------+---------+----------+
// | hex(SHA224(password)) | CRLF | Trojan Request | CRLF | Payload |
// +-----------------------+---------+----------------+---------+----------+
// | 56 | X'0D0A' | Variable | X'0D0A' | Variable |
// +-----------------------+---------+----------------+---------+----------+
// where Trojan Request is a SOCKS5-like request:
// +-----+------+----------+----------+
// | CMD | ATYP | DST.ADDR | DST.PORT |
// +-----+------+----------+----------+
// | 1 | 1 | Variable | 2 |
// +-----+------+----------+----------+
// where:
// o CMD
// o CONNECT X'01'
// o UDP ASSOCIATE X'03'
// o ATYP address type of following address
// o IP V4 address: X'01'
// o DOMAINNAME: X'03'
// o IP V6 address: X'04'
// o DST.ADDR desired destination address
// o DST.PORT desired destination port in network octet order
package trojan
@ -91,7 +67,7 @@ func NewTrojan(s string, d proxy.Dialer, p proxy.Proxy) (*Trojan, error) {
t.tlsConfig = &tls.Config{
ServerName: t.serverName,
InsecureSkipVerify: t.skipVerify,
NextProtos: []string{"http/1.1"},
NextProtos: []string{"http/1.1", "h2"},
ClientSessionCache: tls.NewLRUClientSessionCache(64),
MinVersion: tls.VersionTLS10,
}