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
							
								
									99ad1eb762
								
							
						
					
					
						commit
						050489806c
					
				@ -44,8 +44,7 @@ func DialerFromURL(s string, cDialer Dialer) (Dialer, error) {
 | 
				
			|||||||
	case "socks5":
 | 
						case "socks5":
 | 
				
			||||||
		return NewSOCKS5(addr, user, pass, cDialer, nil)
 | 
							return NewSOCKS5(addr, user, pass, cDialer, nil)
 | 
				
			||||||
	case "ss":
 | 
						case "ss":
 | 
				
			||||||
		p, err := NewSS(addr, user, pass, cDialer, nil)
 | 
							return NewSS(addr, user, pass, cDialer, nil)
 | 
				
			||||||
		return p, err
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return nil, errors.New("unknown schema '" + u.Scheme + "'")
 | 
						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 .
 | 
					// ListenAndServe .
 | 
				
			||||||
func (s *DNS) ListenAndServe() {
 | 
					func (s *DNS) ListenAndServe() {
 | 
				
			||||||
 | 
						go s.ListenAndServeTCP()
 | 
				
			||||||
 | 
						s.ListenAndServeUDP()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ListenAndServeUDP .
 | 
				
			||||||
 | 
					func (s *DNS) ListenAndServeUDP() {
 | 
				
			||||||
	c, err := net.ListenPacket("udp", s.addr)
 | 
						c, err := net.ListenPacket("udp", s.addr)
 | 
				
			||||||
	if err != nil {
 | 
						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
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	defer c.Close()
 | 
						defer c.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logf("listening UDP on %s", s.addr)
 | 
						logf("proxy-dns listening UDP on %s", s.addr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for {
 | 
						for {
 | 
				
			||||||
		data := make([]byte, DNSUDPMaxLen)
 | 
							data := make([]byte, DNSUDPMaxLen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		n, clientAddr, err := c.ReadFrom(data)
 | 
							n, clientAddr, err := c.ReadFrom(data)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			logf("DNS local read error: %v", err)
 | 
								logf("proxy-dns DNS local read error: %v", err)
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -101,11 +107,14 @@ func (s *DNS) ListenAndServe() {
 | 
				
			|||||||
			query := parseQuery(data)
 | 
								query := parseQuery(data)
 | 
				
			||||||
			domain := query.DomainName
 | 
								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)
 | 
								rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer)
 | 
				
			||||||
			if err != nil {
 | 
								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
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			defer rc.Close()
 | 
								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 .
 | 
					// SetServer .
 | 
				
			||||||
func (s *DNS) SetServer(domain, server string) {
 | 
					func (s *DNS) SetServer(domain, server string) {
 | 
				
			||||||
	s.dnsServerMap[domain] = server
 | 
						s.dnsServerMap[domain] = server
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										13
									
								
								dnstun.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								dnstun.go
									
									
									
									
									
								
							@ -9,7 +9,7 @@ type DNSTun struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	raddr string
 | 
						raddr string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	udp *DNS
 | 
						dns *DNS
 | 
				
			||||||
	tcp *TCPTun
 | 
						tcp *TCPTun
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -22,19 +22,14 @@ func NewDNSTun(addr, raddr string, sDialer Dialer) (*DNSTun, error) {
 | 
				
			|||||||
		raddr: raddr,
 | 
							raddr: raddr,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	s.udp, _ = NewDNS(addr, raddr, sDialer)
 | 
						s.dns, _ = NewDNS(addr, raddr, sDialer)
 | 
				
			||||||
	s.tcp, _ = NewTCPTun(addr, raddr, sDialer)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return s, nil
 | 
						return s, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ListenAndServe .
 | 
					// ListenAndServe .
 | 
				
			||||||
func (s *DNSTun) ListenAndServe() {
 | 
					func (s *DNSTun) ListenAndServe() {
 | 
				
			||||||
	if s.udp != nil {
 | 
						if s.dns != nil {
 | 
				
			||||||
		go s.udp.ListenAndServe()
 | 
							go s.dns.ListenAndServe()
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if s.tcp != nil {
 | 
					 | 
				
			||||||
		s.tcp.ListenAndServe()
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -44,8 +44,7 @@ func ServerFromURL(s string, sDialer Dialer) (Server, error) {
 | 
				
			|||||||
	case "socks5":
 | 
						case "socks5":
 | 
				
			||||||
		return NewSOCKS5(addr, user, pass, nil, sDialer)
 | 
							return NewSOCKS5(addr, user, pass, nil, sDialer)
 | 
				
			||||||
	case "ss":
 | 
						case "ss":
 | 
				
			||||||
		p, err := NewSS(addr, user, pass, nil, sDialer)
 | 
							return NewSS(addr, user, pass, nil, sDialer)
 | 
				
			||||||
		return p, err
 | 
					 | 
				
			||||||
	case "redir":
 | 
						case "redir":
 | 
				
			||||||
		return NewRedirProxy(addr, sDialer)
 | 
							return NewRedirProxy(addr, sDialer)
 | 
				
			||||||
	case "tcptun":
 | 
						case "tcptun":
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user