diff options
Diffstat (limited to 'vendor/google.golang.org/grpc/naming')
-rw-r--r-- | vendor/google.golang.org/grpc/naming/dns_resolver.go | 292 | ||||
-rw-r--r-- | vendor/google.golang.org/grpc/naming/go17.go | 34 | ||||
-rw-r--r-- | vendor/google.golang.org/grpc/naming/go18.go | 28 | ||||
-rw-r--r-- | vendor/google.golang.org/grpc/naming/naming.go | 59 |
4 files changed, 413 insertions, 0 deletions
diff --git a/vendor/google.golang.org/grpc/naming/dns_resolver.go b/vendor/google.golang.org/grpc/naming/dns_resolver.go new file mode 100644 index 0000000..efd37e3 --- /dev/null +++ b/vendor/google.golang.org/grpc/naming/dns_resolver.go | |||
@@ -0,0 +1,292 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Copyright 2017 gRPC authors. | ||
4 | * | ||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | * you may not use this file except in compliance with the License. | ||
7 | * You may obtain a copy of the License at | ||
8 | * | ||
9 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | * | ||
11 | * Unless required by applicable law or agreed to in writing, software | ||
12 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | * See the License for the specific language governing permissions and | ||
15 | * limitations under the License. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | package naming | ||
20 | |||
21 | import ( | ||
22 | "errors" | ||
23 | "fmt" | ||
24 | "net" | ||
25 | "strconv" | ||
26 | "time" | ||
27 | |||
28 | "golang.org/x/net/context" | ||
29 | "google.golang.org/grpc/grpclog" | ||
30 | ) | ||
31 | |||
32 | const ( | ||
33 | defaultPort = "443" | ||
34 | defaultFreq = time.Minute * 30 | ||
35 | ) | ||
36 | |||
37 | var ( | ||
38 | errMissingAddr = errors.New("missing address") | ||
39 | errWatcherClose = errors.New("watcher has been closed") | ||
40 | ) | ||
41 | |||
42 | // NewDNSResolverWithFreq creates a DNS Resolver that can resolve DNS names, and | ||
43 | // create watchers that poll the DNS server using the frequency set by freq. | ||
44 | func NewDNSResolverWithFreq(freq time.Duration) (Resolver, error) { | ||
45 | return &dnsResolver{freq: freq}, nil | ||
46 | } | ||
47 | |||
48 | // NewDNSResolver creates a DNS Resolver that can resolve DNS names, and create | ||
49 | // watchers that poll the DNS server using the default frequency defined by defaultFreq. | ||
50 | func NewDNSResolver() (Resolver, error) { | ||
51 | return NewDNSResolverWithFreq(defaultFreq) | ||
52 | } | ||
53 | |||
54 | // dnsResolver handles name resolution for names following the DNS scheme | ||
55 | type dnsResolver struct { | ||
56 | // frequency of polling the DNS server that the watchers created by this resolver will use. | ||
57 | freq time.Duration | ||
58 | } | ||
59 | |||
60 | // formatIP returns ok = false if addr is not a valid textual representation of an IP address. | ||
61 | // If addr is an IPv4 address, return the addr and ok = true. | ||
62 | // If addr is an IPv6 address, return the addr enclosed in square brackets and ok = true. | ||
63 | func formatIP(addr string) (addrIP string, ok bool) { | ||
64 | ip := net.ParseIP(addr) | ||
65 | if ip == nil { | ||
66 | return "", false | ||
67 | } | ||
68 | if ip.To4() != nil { | ||
69 | return addr, true | ||
70 | } | ||
71 | return "[" + addr + "]", true | ||
72 | } | ||
73 | |||
74 | // parseTarget takes the user input target string, returns formatted host and port info. | ||
75 | // If target doesn't specify a port, set the port to be the defaultPort. | ||
76 | // If target is in IPv6 format and host-name is enclosed in sqarue brackets, brackets | ||
77 | // are strippd when setting the host. | ||
78 | // examples: | ||
79 | // target: "www.google.com" returns host: "www.google.com", port: "443" | ||
80 | // target: "ipv4-host:80" returns host: "ipv4-host", port: "80" | ||
81 | // target: "[ipv6-host]" returns host: "ipv6-host", port: "443" | ||
82 | // target: ":80" returns host: "localhost", port: "80" | ||
83 | // target: ":" returns host: "localhost", port: "443" | ||
84 | func parseTarget(target string) (host, port string, err error) { | ||
85 | if target == "" { | ||
86 | return "", "", errMissingAddr | ||
87 | } | ||
88 | |||
89 | if ip := net.ParseIP(target); ip != nil { | ||
90 | // target is an IPv4 or IPv6(without brackets) address | ||
91 | return target, defaultPort, nil | ||
92 | } | ||
93 | if host, port, err := net.SplitHostPort(target); err == nil { | ||
94 | // target has port, i.e ipv4-host:port, [ipv6-host]:port, host-name:port | ||
95 | if host == "" { | ||
96 | // Keep consistent with net.Dial(): If the host is empty, as in ":80", the local system is assumed. | ||
97 | host = "localhost" | ||
98 | } | ||
99 | if port == "" { | ||
100 | // If the port field is empty(target ends with colon), e.g. "[::1]:", defaultPort is used. | ||
101 | port = defaultPort | ||
102 | } | ||
103 | return host, port, nil | ||
104 | } | ||
105 | if host, port, err := net.SplitHostPort(target + ":" + defaultPort); err == nil { | ||
106 | // target doesn't have port | ||
107 | return host, port, nil | ||
108 | } | ||
109 | return "", "", fmt.Errorf("invalid target address %v", target) | ||
110 | } | ||
111 | |||
112 | // Resolve creates a watcher that watches the name resolution of the target. | ||
113 | func (r *dnsResolver) Resolve(target string) (Watcher, error) { | ||
114 | host, port, err := parseTarget(target) | ||
115 | if err != nil { | ||
116 | return nil, err | ||
117 | } | ||
118 | |||
119 | if net.ParseIP(host) != nil { | ||
120 | ipWatcher := &ipWatcher{ | ||
121 | updateChan: make(chan *Update, 1), | ||
122 | } | ||
123 | host, _ = formatIP(host) | ||
124 | ipWatcher.updateChan <- &Update{Op: Add, Addr: host + ":" + port} | ||
125 | return ipWatcher, nil | ||
126 | } | ||
127 | |||
128 | ctx, cancel := context.WithCancel(context.Background()) | ||
129 | return &dnsWatcher{ | ||
130 | r: r, | ||
131 | host: host, | ||
132 | port: port, | ||
133 | ctx: ctx, | ||
134 | cancel: cancel, | ||
135 | t: time.NewTimer(0), | ||
136 | }, nil | ||
137 | } | ||
138 | |||
139 | // dnsWatcher watches for the name resolution update for a specific target | ||
140 | type dnsWatcher struct { | ||
141 | r *dnsResolver | ||
142 | host string | ||
143 | port string | ||
144 | // The latest resolved address list | ||
145 | curAddrs []*Update | ||
146 | ctx context.Context | ||
147 | cancel context.CancelFunc | ||
148 | t *time.Timer | ||
149 | } | ||
150 | |||
151 | // ipWatcher watches for the name resolution update for an IP address. | ||
152 | type ipWatcher struct { | ||
153 | updateChan chan *Update | ||
154 | } | ||
155 | |||
156 | // Next returns the adrress resolution Update for the target. For IP address, | ||
157 | // the resolution is itself, thus polling name server is unncessary. Therefore, | ||
158 | // Next() will return an Update the first time it is called, and will be blocked | ||
159 | // for all following calls as no Update exisits until watcher is closed. | ||
160 | func (i *ipWatcher) Next() ([]*Update, error) { | ||
161 | u, ok := <-i.updateChan | ||
162 | if !ok { | ||
163 | return nil, errWatcherClose | ||
164 | } | ||
165 | return []*Update{u}, nil | ||
166 | } | ||
167 | |||
168 | // Close closes the ipWatcher. | ||
169 | func (i *ipWatcher) Close() { | ||
170 | close(i.updateChan) | ||
171 | } | ||
172 | |||
173 | // AddressType indicates the address type returned by name resolution. | ||
174 | type AddressType uint8 | ||
175 | |||
176 | const ( | ||
177 | // Backend indicates the server is a backend server. | ||
178 | Backend AddressType = iota | ||
179 | // GRPCLB indicates the server is a grpclb load balancer. | ||
180 | GRPCLB | ||
181 | ) | ||
182 | |||
183 | // AddrMetadataGRPCLB contains the information the name resolver for grpclb should provide. The | ||
184 | // name resolver used by the grpclb balancer is required to provide this type of metadata in | ||
185 | // its address updates. | ||
186 | type AddrMetadataGRPCLB struct { | ||
187 | // AddrType is the type of server (grpc load balancer or backend). | ||
188 | AddrType AddressType | ||
189 | // ServerName is the name of the grpc load balancer. Used for authentication. | ||
190 | ServerName string | ||
191 | } | ||
192 | |||
193 | // compileUpdate compares the old resolved addresses and newly resolved addresses, | ||
194 | // and generates an update list | ||
195 | func (w *dnsWatcher) compileUpdate(newAddrs []*Update) []*Update { | ||
196 | update := make(map[Update]bool) | ||
197 | for _, u := range newAddrs { | ||
198 | update[*u] = true | ||
199 | } | ||
200 | for _, u := range w.curAddrs { | ||
201 | if _, ok := update[*u]; ok { | ||
202 | delete(update, *u) | ||
203 | continue | ||
204 | } | ||
205 | update[Update{Addr: u.Addr, Op: Delete, Metadata: u.Metadata}] = true | ||
206 | } | ||
207 | res := make([]*Update, 0, len(update)) | ||
208 | for k := range update { | ||
209 | tmp := k | ||
210 | res = append(res, &tmp) | ||
211 | } | ||
212 | return res | ||
213 | } | ||
214 | |||
215 | func (w *dnsWatcher) lookupSRV() []*Update { | ||
216 | var newAddrs []*Update | ||
217 | _, srvs, err := lookupSRV(w.ctx, "grpclb", "tcp", w.host) | ||
218 | if err != nil { | ||
219 | grpclog.Infof("grpc: failed dns SRV record lookup due to %v.\n", err) | ||
220 | return nil | ||
221 | } | ||
222 | for _, s := range srvs { | ||
223 | lbAddrs, err := lookupHost(w.ctx, s.Target) | ||
224 | if err != nil { | ||
225 | grpclog.Warningf("grpc: failed load banlacer address dns lookup due to %v.\n", err) | ||
226 | continue | ||
227 | } | ||
228 | for _, a := range lbAddrs { | ||
229 | a, ok := formatIP(a) | ||
230 | if !ok { | ||
231 | grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err) | ||
232 | continue | ||
233 | } | ||
234 | newAddrs = append(newAddrs, &Update{Addr: a + ":" + strconv.Itoa(int(s.Port)), | ||
235 | Metadata: AddrMetadataGRPCLB{AddrType: GRPCLB, ServerName: s.Target}}) | ||
236 | } | ||
237 | } | ||
238 | return newAddrs | ||
239 | } | ||
240 | |||
241 | func (w *dnsWatcher) lookupHost() []*Update { | ||
242 | var newAddrs []*Update | ||
243 | addrs, err := lookupHost(w.ctx, w.host) | ||
244 | if err != nil { | ||
245 | grpclog.Warningf("grpc: failed dns A record lookup due to %v.\n", err) | ||
246 | return nil | ||
247 | } | ||
248 | for _, a := range addrs { | ||
249 | a, ok := formatIP(a) | ||
250 | if !ok { | ||
251 | grpclog.Errorf("grpc: failed IP parsing due to %v.\n", err) | ||
252 | continue | ||
253 | } | ||
254 | newAddrs = append(newAddrs, &Update{Addr: a + ":" + w.port}) | ||
255 | } | ||
256 | return newAddrs | ||
257 | } | ||
258 | |||
259 | func (w *dnsWatcher) lookup() []*Update { | ||
260 | newAddrs := w.lookupSRV() | ||
261 | if newAddrs == nil { | ||
262 | // If failed to get any balancer address (either no corresponding SRV for the | ||
263 | // target, or caused by failure during resolution/parsing of the balancer target), | ||
264 | // return any A record info available. | ||
265 | newAddrs = w.lookupHost() | ||
266 | } | ||
267 | result := w.compileUpdate(newAddrs) | ||
268 | w.curAddrs = newAddrs | ||
269 | return result | ||
270 | } | ||
271 | |||
272 | // Next returns the resolved address update(delta) for the target. If there's no | ||
273 | // change, it will sleep for 30 mins and try to resolve again after that. | ||
274 | func (w *dnsWatcher) Next() ([]*Update, error) { | ||
275 | for { | ||
276 | select { | ||
277 | case <-w.ctx.Done(): | ||
278 | return nil, errWatcherClose | ||
279 | case <-w.t.C: | ||
280 | } | ||
281 | result := w.lookup() | ||
282 | // Next lookup should happen after an interval defined by w.r.freq. | ||
283 | w.t.Reset(w.r.freq) | ||
284 | if len(result) > 0 { | ||
285 | return result, nil | ||
286 | } | ||
287 | } | ||
288 | } | ||
289 | |||
290 | func (w *dnsWatcher) Close() { | ||
291 | w.cancel() | ||
292 | } | ||
diff --git a/vendor/google.golang.org/grpc/naming/go17.go b/vendor/google.golang.org/grpc/naming/go17.go new file mode 100644 index 0000000..a537b08 --- /dev/null +++ b/vendor/google.golang.org/grpc/naming/go17.go | |||
@@ -0,0 +1,34 @@ | |||
1 | // +build go1.6, !go1.8 | ||
2 | |||
3 | /* | ||
4 | * | ||
5 | * Copyright 2017 gRPC authors. | ||
6 | * | ||
7 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
8 | * you may not use this file except in compliance with the License. | ||
9 | * You may obtain a copy of the License at | ||
10 | * | ||
11 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
12 | * | ||
13 | * Unless required by applicable law or agreed to in writing, software | ||
14 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
16 | * See the License for the specific language governing permissions and | ||
17 | * limitations under the License. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | package naming | ||
22 | |||
23 | import ( | ||
24 | "net" | ||
25 | |||
26 | "golang.org/x/net/context" | ||
27 | ) | ||
28 | |||
29 | var ( | ||
30 | lookupHost = func(ctx context.Context, host string) ([]string, error) { return net.LookupHost(host) } | ||
31 | lookupSRV = func(ctx context.Context, service, proto, name string) (string, []*net.SRV, error) { | ||
32 | return net.LookupSRV(service, proto, name) | ||
33 | } | ||
34 | ) | ||
diff --git a/vendor/google.golang.org/grpc/naming/go18.go b/vendor/google.golang.org/grpc/naming/go18.go new file mode 100644 index 0000000..b5a0f84 --- /dev/null +++ b/vendor/google.golang.org/grpc/naming/go18.go | |||
@@ -0,0 +1,28 @@ | |||
1 | // +build go1.8 | ||
2 | |||
3 | /* | ||
4 | * | ||
5 | * Copyright 2017 gRPC authors. | ||
6 | * | ||
7 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
8 | * you may not use this file except in compliance with the License. | ||
9 | * You may obtain a copy of the License at | ||
10 | * | ||
11 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
12 | * | ||
13 | * Unless required by applicable law or agreed to in writing, software | ||
14 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
16 | * See the License for the specific language governing permissions and | ||
17 | * limitations under the License. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | package naming | ||
22 | |||
23 | import "net" | ||
24 | |||
25 | var ( | ||
26 | lookupHost = net.DefaultResolver.LookupHost | ||
27 | lookupSRV = net.DefaultResolver.LookupSRV | ||
28 | ) | ||
diff --git a/vendor/google.golang.org/grpc/naming/naming.go b/vendor/google.golang.org/grpc/naming/naming.go new file mode 100644 index 0000000..1af7e32 --- /dev/null +++ b/vendor/google.golang.org/grpc/naming/naming.go | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Copyright 2014 gRPC authors. | ||
4 | * | ||
5 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | * you may not use this file except in compliance with the License. | ||
7 | * You may obtain a copy of the License at | ||
8 | * | ||
9 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | * | ||
11 | * Unless required by applicable law or agreed to in writing, software | ||
12 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | * See the License for the specific language governing permissions and | ||
15 | * limitations under the License. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | // Package naming defines the naming API and related data structures for gRPC. | ||
20 | // The interface is EXPERIMENTAL and may be suject to change. | ||
21 | package naming | ||
22 | |||
23 | // Operation defines the corresponding operations for a name resolution change. | ||
24 | type Operation uint8 | ||
25 | |||
26 | const ( | ||
27 | // Add indicates a new address is added. | ||
28 | Add Operation = iota | ||
29 | // Delete indicates an exisiting address is deleted. | ||
30 | Delete | ||
31 | ) | ||
32 | |||
33 | // Update defines a name resolution update. Notice that it is not valid having both | ||
34 | // empty string Addr and nil Metadata in an Update. | ||
35 | type Update struct { | ||
36 | // Op indicates the operation of the update. | ||
37 | Op Operation | ||
38 | // Addr is the updated address. It is empty string if there is no address update. | ||
39 | Addr string | ||
40 | // Metadata is the updated metadata. It is nil if there is no metadata update. | ||
41 | // Metadata is not required for a custom naming implementation. | ||
42 | Metadata interface{} | ||
43 | } | ||
44 | |||
45 | // Resolver creates a Watcher for a target to track its resolution changes. | ||
46 | type Resolver interface { | ||
47 | // Resolve creates a Watcher for target. | ||
48 | Resolve(target string) (Watcher, error) | ||
49 | } | ||
50 | |||
51 | // Watcher watches for the updates on the specified target. | ||
52 | type Watcher interface { | ||
53 | // Next blocks until an update or error happens. It may return one or more | ||
54 | // updates. The first call should get the full set of the results. It should | ||
55 | // return an error if and only if Watcher cannot recover. | ||
56 | Next() ([]*Update, error) | ||
57 | // Close closes the Watcher. | ||
58 | Close() | ||
59 | } | ||