diff options
Diffstat (limited to 'src/gnunet/service/gns/dns.go')
-rw-r--r-- | src/gnunet/service/gns/dns.go | 61 |
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. |
50 | func queryDNS(id int, name string, server net.IP, kind int, res chan *GNSRecordSet) { | 50 | func 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. |
127 | func (gns *GNSModule) ResolveDNS(name string, servers []string, kind int, pkey *ed25519.PublicKey) (set *GNSRecordSet, err error) { | 132 | func (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) |