|
29 | 29 | #include"req_wrap-inl.h" |
30 | 30 | #include"util-inl.h" |
31 | 31 | #include"uv.h" |
| 32 | +#include"node_errors.h" |
32 | 33 |
|
33 | 34 | #include<cerrno> |
34 | 35 | #include<cstring> |
@@ -2227,6 +2228,70 @@ void SetServers(const FunctionCallbackInfo<Value>& args) { |
2227 | 2228 | args.GetReturnValue().Set(err); |
2228 | 2229 | } |
2229 | 2230 |
|
| 2231 | +voidSetLocalAddress(const FunctionCallbackInfo<Value>& args) { |
| 2232 | + Environment* env = Environment::GetCurrent(args); |
| 2233 | + ChannelWrap* channel; |
| 2234 | +ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); |
| 2235 | + |
| 2236 | +CHECK_EQ(args.Length(), 2); |
| 2237 | +CHECK(args[0]->IsString()); |
| 2238 | + |
| 2239 | + Isolate* isolate = args.GetIsolate(); |
| 2240 | + node::Utf8Value ip0(isolate, args[0]); |
| 2241 | + |
| 2242 | +unsignedchar addr0[sizeof(structin6_addr)]; |
| 2243 | +unsignedchar addr1[sizeof(structin6_addr)]; |
| 2244 | +int type0 = 0; |
| 2245 | + |
| 2246 | +// This function accepts 2 arguments. The first may be either an IPv4 |
| 2247 | +// address or an IPv6 address. If present, the second argument must be the |
| 2248 | +// other type of address. Otherwise, the unspecified type of IP is set |
| 2249 | +// to 0 (any). |
| 2250 | + |
| 2251 | +if (uv_inet_pton(AF_INET, *ip0, &addr0) == 0) { |
| 2252 | +ares_set_local_ip4(channel->cares_channel(), ReadUint32BE(addr0)); |
| 2253 | + type0 = 4; |
| 2254 | + } elseif (uv_inet_pton(AF_INET6, *ip0, &addr0) == 0) { |
| 2255 | +ares_set_local_ip6(channel->cares_channel(), addr0); |
| 2256 | + type0 = 6; |
| 2257 | + } else { |
| 2258 | +THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP address."); |
| 2259 | +return; |
| 2260 | + } |
| 2261 | + |
| 2262 | +if (!args[1]->IsUndefined()) { |
| 2263 | +CHECK(args[1]->IsString()); |
| 2264 | + node::Utf8Value ip1(isolate, args[1]); |
| 2265 | + |
| 2266 | +if (uv_inet_pton(AF_INET, *ip1, &addr1) == 0) { |
| 2267 | +if (type0 == 4) { |
| 2268 | +THROW_ERR_INVALID_ARG_VALUE(env, "Cannot specify two IPv4 addresses."); |
| 2269 | +return; |
| 2270 | + } else { |
| 2271 | +ares_set_local_ip4(channel->cares_channel(), ReadUint32BE(addr1)); |
| 2272 | + } |
| 2273 | + } elseif (uv_inet_pton(AF_INET6, *ip1, &addr1) == 0) { |
| 2274 | +if (type0 == 6) { |
| 2275 | +THROW_ERR_INVALID_ARG_VALUE(env, "Cannot specify two IPv6 addresses."); |
| 2276 | +return; |
| 2277 | + } else { |
| 2278 | +ares_set_local_ip6(channel->cares_channel(), addr1); |
| 2279 | + } |
| 2280 | + } else { |
| 2281 | +THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP address."); |
| 2282 | +return; |
| 2283 | + } |
| 2284 | + } else { |
| 2285 | +// No second arg specifed |
| 2286 | +if (type0 == 4) { |
| 2287 | +memset(&addr1, 0, sizeof(addr1)); |
| 2288 | +ares_set_local_ip6(channel->cares_channel(), addr1); |
| 2289 | + } else { |
| 2290 | +ares_set_local_ip4(channel->cares_channel(), 0); |
| 2291 | + } |
| 2292 | + } |
| 2293 | +} |
| 2294 | + |
2230 | 2295 | voidCancel(const FunctionCallbackInfo<Value>& args) { |
2231 | 2296 | ChannelWrap* channel; |
2232 | 2297 | ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); |
@@ -2329,6 +2394,7 @@ void Initialize(Local<Object> target, |
2329 | 2394 |
|
2330 | 2395 | env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers); |
2331 | 2396 | env->SetProtoMethod(channel_wrap, "setServers", SetServers); |
| 2397 | + env->SetProtoMethod(channel_wrap, "setLocalAddress", SetLocalAddress); |
2332 | 2398 | env->SetProtoMethod(channel_wrap, "cancel", Cancel); |
2333 | 2399 |
|
2334 | 2400 | Local<String> channelWrapString = |
|
0 commit comments