mirror of
				https://github.com/nadoo/glider.git
				synced 2025-11-04 07:42:38 +08:00 
			
		
		
		
	dns: move tcp and udp process to handleReqMsg function
This commit is contained in:
		
							parent
							
								
									a652f8db04
								
							
						
					
					
						commit
						969034fb97
					
				
							
								
								
									
										135
									
								
								dns.go
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								dns.go
									
									
									
									
									
								
							@ -4,8 +4,7 @@ package main
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/binary"
 | 
						"encoding/binary"
 | 
				
			||||||
	"encoding/hex"
 | 
						"errors"
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"io"
 | 
						"io"
 | 
				
			||||||
	"net"
 | 
						"net"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
@ -110,77 +109,15 @@ func (s *DNS) ListenAndServeUDP() {
 | 
				
			|||||||
		data = data[:n]
 | 
							data = data[:n]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
			query := parseQuery(data)
 | 
					 | 
				
			||||||
			domain := query.DomainName
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			dnsServer := s.GetServer(domain)
 | 
								_, respMsg := s.handleReqMsg(uint16(len(data)), data)
 | 
				
			||||||
			if s.tunnel {
 | 
					 | 
				
			||||||
				dnsServer = s.dnsServer
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer)
 | 
								_, err = c.WriteTo(respMsg, clientAddr)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
				logf("proxy-dns failed to connect to server %v: %v", dnsServer, err)
 | 
									logf("proxy-dns error in local write: %s\n", err)
 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			defer rc.Close()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// 2 bytes length after tcp header, before dns message
 | 
					 | 
				
			||||||
			reqLen := make([]byte, 2)
 | 
					 | 
				
			||||||
			binary.BigEndian.PutUint16(reqLen, uint16(len(data)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			rc.Write(reqLen)
 | 
					 | 
				
			||||||
			rc.Write(data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// fmt.Printf("dns req len %d:\n%s\n\n", reqLen, hex.Dump(data[:]))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var respLen uint16
 | 
					 | 
				
			||||||
			err = binary.Read(rc, binary.BigEndian, &respLen)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				logf("proxy-dns error in read respLen %s\n", err)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			respMsg := make([]byte, respLen)
 | 
								// logf("proxy-dns %s <-> %s, type: %d, %s: %s", clientAddr.String(), dnsServer, query.QueryType, domain, ip)
 | 
				
			||||||
			_, err = io.ReadFull(rc, respMsg)
 | 
					 | 
				
			||||||
			if err != nil {
 | 
					 | 
				
			||||||
				logf("proxy-dns error in read respMsg %s\n", err)
 | 
					 | 
				
			||||||
				return
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// fmt.Printf("dns resp len %d:\n%s\n\n", respLen, hex.Dump(respMsg[:]))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			var ip string
 | 
					 | 
				
			||||||
			// length is not needed in udp dns response. (2 bytes)
 | 
					 | 
				
			||||||
			// SEE RFC1035, section 4.2.2 TCP: The message is prefixed with a two byte length field which gives the message length, excluding the two byte length field.
 | 
					 | 
				
			||||||
			if respLen > 0 {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				// run handle functions before send to client so RULE and IPSET can take effect
 | 
					 | 
				
			||||||
				// TODO: add PRE_HANDLERS
 | 
					 | 
				
			||||||
				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)
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				_, err = c.WriteTo(respMsg, clientAddr)
 | 
					 | 
				
			||||||
				if err != nil {
 | 
					 | 
				
			||||||
					logf("proxy-dns error in local write: %s\n", err)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			logf("proxy-dns %s <-> %s, type: %d, %s: %s", clientAddr.String(), dnsServer, query.QueryType, domain, ip)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -223,19 +160,37 @@ func (s *DNS) ServeTCP(c net.Conn) {
 | 
				
			|||||||
	reqMsg := make([]byte, reqLen)
 | 
						reqMsg := make([]byte, reqLen)
 | 
				
			||||||
	_, err := io.ReadFull(c, reqMsg)
 | 
						_, err := io.ReadFull(c, reqMsg)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logf("proxy-dns-tcp error in read reqMsg %s\n", err)
 | 
							logf("proxy-dns-tcp error in read reqMsg %s", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	query := parseQuery(reqMsg)
 | 
						respLen, respMsg := s.handleReqMsg(reqLen, reqMsg)
 | 
				
			||||||
	domain := query.DomainName
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dnsServer := s.GetServer(domain)
 | 
						if err := binary.Write(c, binary.BigEndian, respLen); err != nil {
 | 
				
			||||||
 | 
							logf("proxy-dns-tcp error in local write respLen: %s\n", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if err := binary.Write(c, binary.BigEndian, respMsg); err != nil {
 | 
				
			||||||
 | 
							logf("proxy-dns-tcp error in local write respMsg: %s\n", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// logf("proxy-dns-tcp %s <-> %s, type: %d, %s: %s", c.RemoteAddr(), dnsServer, query.QueryType, domain, ip)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// handle request msg and return response msg
 | 
				
			||||||
 | 
					func (s *DNS) handleReqMsg(reqLen uint16, reqMsg []byte) (respLen uint16, respMsg []byte) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						query, err := parseQuery(reqMsg)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							logf("proxy-dns-tcp error in parseQuery reqMsg %s", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dnsServer := s.GetServer(query.DomainName)
 | 
				
			||||||
	if s.tunnel {
 | 
						if s.tunnel {
 | 
				
			||||||
		dnsServer = s.dnsServer
 | 
							dnsServer = s.dnsServer
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc, err := s.sDialer.NextDialer(domain+":53").Dial("tcp", dnsServer)
 | 
						rc, err := s.sDialer.NextDialer(query.DomainName+":53").Dial("tcp", dnsServer)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logf("proxy-dns failed to connect to server %v: %v", dnsServer, err)
 | 
							logf("proxy-dns failed to connect to server %v: %v", dnsServer, err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
@ -243,30 +198,34 @@ func (s *DNS) ServeTCP(c net.Conn) {
 | 
				
			|||||||
	defer rc.Close()
 | 
						defer rc.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := binary.Write(rc, binary.BigEndian, reqLen); err != nil {
 | 
						if err := binary.Write(rc, binary.BigEndian, reqLen); err != nil {
 | 
				
			||||||
 | 
							logf("proxy-dns failed to connect to server %v: %v", dnsServer, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := binary.Write(rc, binary.BigEndian, reqMsg); err != nil {
 | 
						if err := binary.Write(rc, binary.BigEndian, reqMsg); err != nil {
 | 
				
			||||||
 | 
							logf("proxy-dns failed to connect to server %v: %v", dnsServer, err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var respLen uint16
 | 
					 | 
				
			||||||
	if err := binary.Read(rc, binary.BigEndian, &respLen); err != nil {
 | 
						if err := binary.Read(rc, binary.BigEndian, &respLen); err != nil {
 | 
				
			||||||
		logf("proxy-dns-tcp failed to read response length: %v", err)
 | 
							logf("proxy-dns-tcp failed to read response length: %v", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	respMsg := make([]byte, respLen)
 | 
						respMsg = make([]byte, respLen)
 | 
				
			||||||
	_, err = io.ReadFull(rc, respMsg)
 | 
						_, err = io.ReadFull(rc, respMsg)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		logf("proxy-dns-tcp error in read respMsg %s\n", err)
 | 
							logf("proxy-dns-tcp error in read respMsg %s\n", err)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fmt.Printf("dns resp len %d:\n%s\n\n", respLen, hex.Dump(respMsg[:]))
 | 
						// fmt.Printf("dns resp len %d:\n%s\n\n", respLen, hex.Dump(respMsg[:]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var ip string
 | 
						var ip string
 | 
				
			||||||
	if respLen > 0 {
 | 
						if respLen > 0 {
 | 
				
			||||||
		query := parseQuery(respMsg)
 | 
							query, err := parseQuery(respMsg)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								logf("proxy-dns error in parseQuery respMsg %s", err)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (query.QueryType == DNSQueryTypeA || query.QueryType == DNSQueryTypeAAAA) &&
 | 
							if (query.QueryType == DNSQueryTypeA || query.QueryType == DNSQueryTypeAAAA) &&
 | 
				
			||||||
			len(respMsg) > query.Offset {
 | 
								len(respMsg) > query.Offset {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -283,16 +242,9 @@ func (s *DNS) ServeTCP(c net.Conn) {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if err := binary.Write(c, binary.BigEndian, respLen); err != nil {
 | 
					 | 
				
			||||||
			logf("proxy-dns-tcp error in local write respLen: %s\n", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if err := binary.Write(c, binary.BigEndian, respMsg); err != nil {
 | 
					 | 
				
			||||||
			logf("proxy-dns-tcp error in local write respMsg: %s\n", err)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	logf("proxy-dns-tcp %s <-> %s, type: %d, %s: %s", c.RemoteAddr(), dnsServer, query.QueryType, domain, ip)
 | 
						return
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SetServer .
 | 
					// SetServer .
 | 
				
			||||||
@ -321,7 +273,7 @@ func (s *DNS) AddAnswerHandler(h DNSAnswerHandler) {
 | 
				
			|||||||
	s.answerHandlers = append(s.answerHandlers, h)
 | 
						s.answerHandlers = append(s.answerHandlers, h)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseQuery(p []byte) *dnsQuery {
 | 
					func parseQuery(p []byte) (*dnsQuery, error) {
 | 
				
			||||||
	q := &dnsQuery{}
 | 
						q := &dnsQuery{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var i int
 | 
						var i int
 | 
				
			||||||
@ -341,11 +293,16 @@ func parseQuery(p []byte) *dnsQuery {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	q.DomainName = string(domain[:len(domain)-1])
 | 
						q.DomainName = string(domain[:len(domain)-1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if len(p) < i+4 {
 | 
				
			||||||
 | 
							return nil, errors.New("parseQuery error, not enough data")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	q.QueryType = binary.BigEndian.Uint16(p[i:])
 | 
						q.QueryType = binary.BigEndian.Uint16(p[i:])
 | 
				
			||||||
	q.QueryClass = binary.BigEndian.Uint16(p[i+2:])
 | 
						q.QueryClass = binary.BigEndian.Uint16(p[i+2:])
 | 
				
			||||||
	q.Offset = i + 4
 | 
						q.Offset = i + 4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return q
 | 
						return q, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseAnswers(p []byte) []*dnsAnswer {
 | 
					func parseAnswers(p []byte) []*dnsAnswer {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user