|  | 
| 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> | 
| @@ -2149,6 +2150,70 @@ void SetServers(const FunctionCallbackInfo<Value>& args) { | 
| 2149 | 2150 |   args.GetReturnValue().Set(err); | 
| 2150 | 2151 | } | 
| 2151 | 2152 | 
 | 
|  | 2153 | +void SetLocalAddress(const FunctionCallbackInfo<Value>& args) { | 
|  | 2154 | +  Environment* env = Environment::GetCurrent(args); | 
|  | 2155 | +  ChannelWrap* channel; | 
|  | 2156 | +  ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); | 
|  | 2157 | + | 
|  | 2158 | +  CHECK_EQ(args.Length(), 2); | 
|  | 2159 | +  CHECK(args[0]->IsString()); | 
|  | 2160 | + | 
|  | 2161 | +  Isolate* isolate = args.GetIsolate(); | 
|  | 2162 | +  node::Utf8Value ip0(isolate, args[0]); | 
|  | 2163 | + | 
|  | 2164 | +  unsigned char addr0[sizeof(struct in6_addr)]; | 
|  | 2165 | +  unsigned char addr1[sizeof(struct in6_addr)]; | 
|  | 2166 | +  int type0 = 0; | 
|  | 2167 | + | 
|  | 2168 | +  // This function accepts 2 arguments.  The first may be either an IPv4 | 
|  | 2169 | +  // address or an IPv6 address.  If present, the second argument must be the | 
|  | 2170 | +  // other type of address.  Otherwise, the unspecified type of IP is set | 
|  | 2171 | +  // to 0 (any). | 
|  | 2172 | + | 
|  | 2173 | +  if (uv_inet_pton(AF_INET, *ip0, &addr0) == 0) { | 
|  | 2174 | +    ares_set_local_ip4(channel->cares_channel(), ReadUint32BE(addr0)); | 
|  | 2175 | +    type0 = 4; | 
|  | 2176 | +  } else if (uv_inet_pton(AF_INET6, *ip0, &addr0) == 0) { | 
|  | 2177 | +    ares_set_local_ip6(channel->cares_channel(), addr0); | 
|  | 2178 | +    type0 = 6; | 
|  | 2179 | +  } else { | 
|  | 2180 | +    THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP address."); | 
|  | 2181 | +    return; | 
|  | 2182 | +  } | 
|  | 2183 | + | 
|  | 2184 | +  if (!args[1]->IsUndefined()) { | 
|  | 2185 | +    CHECK(args[1]->IsString()); | 
|  | 2186 | +    node::Utf8Value ip1(isolate, args[1]); | 
|  | 2187 | + | 
|  | 2188 | +    if (uv_inet_pton(AF_INET, *ip1, &addr1) == 0) { | 
|  | 2189 | +      if (type0 == 4) { | 
|  | 2190 | +        THROW_ERR_INVALID_ARG_VALUE(env, "Cannot specify two IPv4 addresses."); | 
|  | 2191 | +        return; | 
|  | 2192 | +      } else { | 
|  | 2193 | +        ares_set_local_ip4(channel->cares_channel(), ReadUint32BE(addr1)); | 
|  | 2194 | +      } | 
|  | 2195 | +    } else if (uv_inet_pton(AF_INET6, *ip1, &addr1) == 0) { | 
|  | 2196 | +      if (type0 == 6) { | 
|  | 2197 | +        THROW_ERR_INVALID_ARG_VALUE(env, "Cannot specify two IPv6 addresses."); | 
|  | 2198 | +        return; | 
|  | 2199 | +      } else { | 
|  | 2200 | +        ares_set_local_ip6(channel->cares_channel(), addr1); | 
|  | 2201 | +      } | 
|  | 2202 | +    } else { | 
|  | 2203 | +      THROW_ERR_INVALID_ARG_VALUE(env, "Invalid IP address."); | 
|  | 2204 | +      return; | 
|  | 2205 | +    } | 
|  | 2206 | +  } else { | 
|  | 2207 | +    // No second arg specifed | 
|  | 2208 | +    if (type0 == 4) { | 
|  | 2209 | +      memset(&addr1, 0, sizeof(addr1)); | 
|  | 2210 | +      ares_set_local_ip6(channel->cares_channel(), addr1); | 
|  | 2211 | +    } else { | 
|  | 2212 | +      ares_set_local_ip4(channel->cares_channel(), 0); | 
|  | 2213 | +    } | 
|  | 2214 | +  } | 
|  | 2215 | +} | 
|  | 2216 | + | 
| 2152 | 2217 | void Cancel(const FunctionCallbackInfo<Value>& args) { | 
| 2153 | 2218 |   ChannelWrap* channel; | 
| 2154 | 2219 |   ASSIGN_OR_RETURN_UNWRAP(&channel, args.Holder()); | 
| @@ -2250,6 +2315,7 @@ void Initialize(Local<Object> target, | 
| 2250 | 2315 | 
 | 
| 2251 | 2316 |   env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers); | 
| 2252 | 2317 |   env->SetProtoMethod(channel_wrap, "setServers", SetServers); | 
|  | 2318 | +  env->SetProtoMethod(channel_wrap, "setLocalAddress", SetLocalAddress); | 
| 2253 | 2319 |   env->SetProtoMethod(channel_wrap, "cancel", Cancel); | 
| 2254 | 2320 | 
 | 
| 2255 | 2321 |   Local<String> channelWrapString = | 
|  | 
0 commit comments