mirror of
				https://github.com/nadoo/glider.git
				synced 2025-11-04 07:42:38 +08:00 
			
		
		
		
	dns: add tcp support
This commit is contained in:
		
							parent
							
								
									6e3423588a
								
							
						
					
					
						commit
						238702f159
					
				@ -44,8 +44,7 @@ func DialerFromURL(s string, cDialer Dialer) (Dialer, error) {
 | 
			
		||||
	case "socks5":
 | 
			
		||||
		return NewSOCKS5(addr, user, pass, cDialer, nil)
 | 
			
		||||
	case "ss":
 | 
			
		||||
		p, err := NewSS(addr, user, pass, cDialer, nil)
 | 
			
		||||
		return p, err
 | 
			
		||||
		return NewSS(addr, user, pass, cDialer, nil)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil, errors.New("unknown schema '" + u.Scheme + "'")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										118
									
								
								dns.go
									
									
									
									
									
								
							
							
						
						
									
										118
									
								
								dns.go
									
									
									
									
									
								
							@ -77,21 +77,27 @@ func NewDNS(addr, raddr string, sDialer Dialer) (*DNS, error) {
 | 
			
		||||
 | 
			
		||||
// ListenAndServe .
 | 
			
		||||
func (s *DNS) ListenAndServe() {
 | 
			
		||||
	go s.ListenAndServeTCP()
 | 
			
		||||
	s.ListenAndServeUDP()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenAndServeUDP .
 | 
			
		||||
func (s *DNS) ListenAndServeUDP() {
 | 
			
		||||
	c, err := net.ListenPacket("udp", s.addr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logf("failed to listen on %s: %v", s.addr, err)
 | 
			
		||||
		logf("proxy-dns failed to listen on %s: %v", s.addr, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer c.Close()
 | 
			
		||||
 | 
			
		||||
	logf("listening UDP on %s", s.addr)
 | 
			
		||||
	logf("proxy-dns listening UDP on %s", s.addr)
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		data := make([]byte, DNSUDPMaxLen)
 | 
			
		||||
 | 
			
		||||
		n, clientAddr, err := c.ReadFrom(data)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logf("DNS local read error: %v", err)
 | 
			
		||||
			logf("proxy-dns DNS local read error: %v", err)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -101,11 +107,14 @@ func (s *DNS) ListenAndServe() {
 | 
			
		||||
			query := parseQuery(data)
 | 
			
		||||
			domain := query.DomainName
 | 
			
		||||
 | 
			
		||||
			dnsServer := s.GetServer(domain)
 | 
			
		||||
			dnsServer := s.dnsServer
 | 
			
		||||
			if dnsServer == "" {
 | 
			
		||||
				dnsServer = s.GetServer(domain)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				logf("failed to connect to server %v: %v", dnsServer, err)
 | 
			
		||||
				logf("proxy-dns failed to connect to server %v: %v", dnsServer, err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			defer rc.Close()
 | 
			
		||||
@ -170,6 +179,105 @@ func (s *DNS) ListenAndServe() {
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenAndServeTCP .
 | 
			
		||||
func (s *DNS) ListenAndServeTCP() {
 | 
			
		||||
	l, err := net.Listen("tcp", s.addr)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logf("proxy-dns-tcp error: %v", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logf("proxy-dns-tcp listening TCP on %s", s.addr)
 | 
			
		||||
 | 
			
		||||
	for {
 | 
			
		||||
		c, err := l.Accept()
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			logf("proxy-dns-tcp error: failed to accept: %v", err)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		go s.ServeTCP(c)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ServeTCP .
 | 
			
		||||
func (s *DNS) ServeTCP(c net.Conn) {
 | 
			
		||||
	defer c.Close()
 | 
			
		||||
 | 
			
		||||
	if c, ok := c.(*net.TCPConn); ok {
 | 
			
		||||
		c.SetKeepAlive(true)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var reqLen uint16
 | 
			
		||||
	if err := binary.Read(c, binary.BigEndian, &reqLen); err != nil {
 | 
			
		||||
		logf("proxy-dns-tcp failed to read request length: %v", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	reqMsg := make([]byte, reqLen)
 | 
			
		||||
	_, err := io.ReadFull(c, reqMsg)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logf("proxy-dns-tcp error in read reqMsg %s\n", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	query := parseQuery(reqMsg)
 | 
			
		||||
	domain := query.DomainName
 | 
			
		||||
 | 
			
		||||
	dnsServer := s.dnsServer
 | 
			
		||||
	if dnsServer == "" {
 | 
			
		||||
		dnsServer = s.GetServer(domain)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logf("proxy-dns failed to connect to server %v: %v", dnsServer, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	defer rc.Close()
 | 
			
		||||
 | 
			
		||||
	binary.Write(rc, binary.BigEndian, reqLen)
 | 
			
		||||
	binary.Write(rc, binary.BigEndian, reqMsg)
 | 
			
		||||
 | 
			
		||||
	var respLen uint16
 | 
			
		||||
	if err := binary.Read(rc, binary.BigEndian, &respLen); err != nil {
 | 
			
		||||
		logf("proxy-dns-tcp failed to read response length: %v", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	respMsg := make([]byte, respLen)
 | 
			
		||||
	_, err = io.ReadFull(rc, respMsg)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logf("proxy-dns-tcp error in read respMsg %s\n", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var ip string
 | 
			
		||||
	if respLen > 0 {
 | 
			
		||||
		query := parseQuery(respMsg)
 | 
			
		||||
		if (query.QueryType == DNSQueryTypeA || query.QueryType == DNSQueryTypeAAAA) &&
 | 
			
		||||
			len(respMsg) > query.Offset {
 | 
			
		||||
 | 
			
		||||
			answers := parseAnswers(respMsg[query.Offset:])
 | 
			
		||||
 | 
			
		||||
			for _, answer := range answers {
 | 
			
		||||
				if answer.IP != "" {
 | 
			
		||||
					ip += answer.IP + ","
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				for _, h := range s.answerHandlers {
 | 
			
		||||
					h(query.DomainName, answer.IP)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		binary.Write(c, binary.BigEndian, respLen)
 | 
			
		||||
		binary.Write(c, binary.BigEndian, respMsg)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logf("proxy-dns-tcp %s <-> %s, type: %d, %s: %s", c.RemoteAddr(), dnsServer, query.QueryType, domain, ip)
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SetServer .
 | 
			
		||||
func (s *DNS) SetServer(domain, server string) {
 | 
			
		||||
	s.dnsServerMap[domain] = server
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								dnstun.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								dnstun.go
									
									
									
									
									
								
							@ -9,7 +9,7 @@ type DNSTun struct {
 | 
			
		||||
 | 
			
		||||
	raddr string
 | 
			
		||||
 | 
			
		||||
	udp *DNS
 | 
			
		||||
	dns *DNS
 | 
			
		||||
	tcp *TCPTun
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -22,19 +22,14 @@ func NewDNSTun(addr, raddr string, sDialer Dialer) (*DNSTun, error) {
 | 
			
		||||
		raddr: raddr,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	s.udp, _ = NewDNS(addr, raddr, sDialer)
 | 
			
		||||
	s.tcp, _ = NewTCPTun(addr, raddr, sDialer)
 | 
			
		||||
	s.dns, _ = NewDNS(addr, raddr, sDialer)
 | 
			
		||||
 | 
			
		||||
	return s, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListenAndServe .
 | 
			
		||||
func (s *DNSTun) ListenAndServe() {
 | 
			
		||||
	if s.udp != nil {
 | 
			
		||||
		go s.udp.ListenAndServe()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if s.tcp != nil {
 | 
			
		||||
		s.tcp.ListenAndServe()
 | 
			
		||||
	if s.dns != nil {
 | 
			
		||||
		go s.dns.ListenAndServe()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -44,8 +44,7 @@ func ServerFromURL(s string, sDialer Dialer) (Server, error) {
 | 
			
		||||
	case "socks5":
 | 
			
		||||
		return NewSOCKS5(addr, user, pass, nil, sDialer)
 | 
			
		||||
	case "ss":
 | 
			
		||||
		p, err := NewSS(addr, user, pass, nil, sDialer)
 | 
			
		||||
		return p, err
 | 
			
		||||
		return NewSS(addr, user, pass, nil, sDialer)
 | 
			
		||||
	case "redir":
 | 
			
		||||
		return NewRedirProxy(addr, sDialer)
 | 
			
		||||
	case "tcptun":
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user