aboutsummaryrefslogtreecommitdiff
path: root/src/gnunet/service/gns/dns.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/gnunet/service/gns/dns.go')
-rw-r--r--src/gnunet/service/gns/dns.go61
1 files changed, 37 insertions, 24 deletions
diff --git a/src/gnunet/service/gns/dns.go b/src/gnunet/service/gns/dns.go
index 2ebe331..fe138b0 100644
--- a/src/gnunet/service/gns/dns.go
+++ b/src/gnunet/service/gns/dns.go
@@ -47,7 +47,7 @@ func DNSNameFromBytes(b []byte, offset int) (int, string) {
47 47
48// queryDNS resolves a name on a given nameserver and delivers all matching 48// queryDNS resolves a name on a given nameserver and delivers all matching
49// resource record (of type 'kind') to the result channel. 49// resource record (of type 'kind') to the result channel.
50func queryDNS(id int, name string, server net.IP, kind int, res chan *GNSRecordSet) { 50func queryDNS(id int, name string, server net.IP, kind RRTypeList, res chan *GNSRecordSet) {
51 logger.Printf(logger.DBG, "[dns][%d] Starting query for '%s' on '%s'...\n", id, name, server.String()) 51 logger.Printf(logger.DBG, "[dns][%d] Starting query for '%s' on '%s'...\n", id, name, server.String())
52 52
53 // assemble query 53 // assemble query
@@ -91,27 +91,32 @@ func queryDNS(id int, name string, server net.IP, kind int, res chan *GNSRecordS
91 } 91 }
92 set := NewGNSRecordSet() 92 set := NewGNSRecordSet()
93 for _, record := range in.Answer { 93 for _, record := range in.Answer {
94 // create a new GNS resource record 94 // check if answer record is of requested type
95 rr := new(message.GNSResourceRecord) 95 if kind.HasType(int(record.Header().Rrtype)) {
96 rr.Expires = util.AbsoluteTimeNever() 96 // get wire-format of resource record
97 rr.Flags = 0 97 buf := make([]byte, 2048)
98 rr.Type = uint32(record.Header().Rrtype) 98 n, err := dns.PackRR(record, buf, 0, nil, false)
99 rr.Size = uint32(record.Header().Rdlength) 99 if err != nil {
100 rr.Data = make([]byte, rr.Size) 100 logger.Printf(logger.WARN, "[dns][%d] Failed to get RR data for %s\n", id, err.Error())
101 continue
102 }
101 103
102 // get wire-format of resource record 104 // create a new GNS resource record
103 buf := make([]byte, 2048) 105 rr := new(message.GNSResourceRecord)
104 n, err := dns.PackRR(record, buf, 0, nil, false) 106 expires := time.Now().Add(time.Duration(record.Header().Ttl) * time.Second)
105 if err != nil { 107 rr.Expires = util.NewAbsoluteTime(expires)
106 logger.Printf(logger.WARN, "[dns][%d] Failed to get RR data for %s\n", id, err.Error()) 108 rr.Flags = 0
107 continue 109 rr.Type = uint32(record.Header().Rrtype)
108 } 110 rr.Size = uint32(record.Header().Rdlength)
109 if n < int(rr.Size) { 111 rr.Data = make([]byte, rr.Size)
110 logger.Printf(logger.WARN, "[dns][%d] Nit enough data in RR (%d != %d)\n", id, n, rr.Size) 112
111 continue 113 if n < int(rr.Size) {
114 logger.Printf(logger.WARN, "[dns][%d] Not enough data in RR (%d != %d)\n", id, n, rr.Size)
115 continue
116 }
117 copy(rr.Data, buf[n-int(rr.Size):])
118 set.AddRecord(rr)
112 } 119 }
113 copy(rr.Data, buf[n-int(rr.Size):])
114 set.AddRecord(rr)
115 } 120 }
116 logger.Printf(logger.WARN, "[dns][%d] %d resource records extracted from response (%d/5).\n", id, set.Count, retry+1) 121 logger.Printf(logger.WARN, "[dns][%d] %d resource records extracted from response (%d/5).\n", id, set.Count, retry+1)
117 res <- set 122 res <- set
@@ -124,7 +129,7 @@ func queryDNS(id int, name string, server net.IP, kind int, res chan *GNSRecordS
124// ResolveDNS resolves a name in DNS. Multiple DNS servers are queried in 129// ResolveDNS resolves a name in DNS. Multiple DNS servers are queried in
125// parallel; the first result delivered by any of the servers is returned 130// parallel; the first result delivered by any of the servers is returned
126// as the result list of matching resource records. 131// as the result list of matching resource records.
127func (gns *GNSModule) ResolveDNS(name string, servers []string, kind int, pkey *ed25519.PublicKey) (set *GNSRecordSet, err error) { 132func (gns *GNSModule) ResolveDNS(name string, servers []string, kind RRTypeList, pkey *ed25519.PublicKey) (set *GNSRecordSet, err error) {
128 logger.Printf(logger.DBG, "[dns] Resolution of '%s' starting...\n", name) 133 logger.Printf(logger.DBG, "[dns] Resolution of '%s' starting...\n", name)
129 134
130 // start DNS queries concurrently 135 // start DNS queries concurrently
@@ -133,20 +138,22 @@ func (gns *GNSModule) ResolveDNS(name string, servers []string, kind int, pkey *
133 for idx, srv := range servers { 138 for idx, srv := range servers {
134 // check if srv is an IPv4/IPv6 address 139 // check if srv is an IPv4/IPv6 address
135 addr := net.ParseIP(srv) 140 addr := net.ParseIP(srv)
141 logger.Printf(logger.DBG, "ParseIP('%s', len=%d) --> %v\n", srv, len(srv), addr)
136 if addr == nil { 142 if addr == nil {
143 query := NewRRTypeList(enums.GNS_TYPE_DNS_A, enums.GNS_TYPE_DNS_AAAA)
137 // no; resolve server name in GNS 144 // no; resolve server name in GNS
138 if strings.HasSuffix(srv, ".+") { 145 if strings.HasSuffix(srv, ".+") {
139 // resolve server name relative to current zone 146 // resolve server name relative to current zone
140 zone := util.EncodeBinaryToString(pkey.Bytes()) 147 zone := util.EncodeBinaryToString(pkey.Bytes())
141 srv = strings.TrimSuffix(srv, ".+") 148 srv = strings.TrimSuffix(srv, ".+")
142 set, err = gns.Resolve(srv, pkey, enums.GNS_TYPE_ANY, enums.GNS_LO_DEFAULT) 149 set, err = gns.Resolve(srv, pkey, query, enums.GNS_LO_DEFAULT)
143 if err != nil { 150 if err != nil {
144 logger.Printf(logger.ERROR, "[dns] Can't resolve NS server '%s' in '%s'\n", srv, zone) 151 logger.Printf(logger.ERROR, "[dns] Can't resolve NS server '%s' in '%s'\n", srv, zone)
145 continue 152 continue
146 } 153 }
147 } else { 154 } else {
148 // resolve absolute GNS name (MUST end in a PKEY) 155 // resolve absolute GNS name (name MUST end in a PKEY)
149 set, err = gns.Resolve(srv, nil, enums.GNS_TYPE_ANY, enums.GNS_LO_DEFAULT) 156 set, err = gns.Resolve(srv, nil, query, enums.GNS_LO_DEFAULT)
150 if err != nil { 157 if err != nil {
151 logger.Printf(logger.ERROR, "[dns] Can't resolve NS server '%s'\n", srv) 158 logger.Printf(logger.ERROR, "[dns] Can't resolve NS server '%s'\n", srv)
152 continue 159 continue
@@ -158,11 +165,17 @@ func (gns *GNSModule) ResolveDNS(name string, servers []string, kind int, pkey *
158 switch int(rec.Type) { 165 switch int(rec.Type) {
159 case enums.GNS_TYPE_DNS_AAAA: 166 case enums.GNS_TYPE_DNS_AAAA:
160 addr = net.IP(rec.Data) 167 addr = net.IP(rec.Data)
168 // we prefer IPv6
161 break rec_loop 169 break rec_loop
162 case enums.GNS_TYPE_DNS_A: 170 case enums.GNS_TYPE_DNS_A:
163 addr = net.IP(rec.Data) 171 addr = net.IP(rec.Data)
164 } 172 }
165 } 173 }
174 // check if we have an IP address available
175 if addr == nil {
176 logger.Printf(logger.WARN, "[dns] No IP address for nameserver in GNS")
177 continue
178 }
166 } 179 }
167 // query DNS concurrently 180 // query DNS concurrently
168 go queryDNS(idx, name, addr, kind, res) 181 go queryDNS(idx, name, addr, kind, res)