15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "fake_ppapi/fake_host_resolver_interface.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <netinet/in.h>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "fake_ppapi/fake_pepper_interface.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "fake_ppapi/fake_resource_manager.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "fake_ppapi/fake_var_manager.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "gtest/gtest.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace  {
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class FakeHostResolverResource : public FakeResource {
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeHostResolverResource() : resolved(false) {}
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static const char* classname() { return "FakeHostResolverResource"; }
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool resolved;
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  PP_HostResolver_Hint hints;
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int32_t RunCompletionCallback(PP_CompletionCallback* callback, int32_t result) {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (callback->func) {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_RunCompletionCallback(callback, result);
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return PP_OK_COMPLETIONPENDING;
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return result;
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)FakeHostResolverInterface::FakeHostResolverInterface(FakePepperInterface* ppapi)
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    : ppapi_(ppapi) {}
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PP_Resource FakeHostResolverInterface::Create(PP_Instance instance) {
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (instance != ppapi_->GetInstance())
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return PP_ERROR_BADRESOURCE;
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeHostResolverResource* resolver_resource = new FakeHostResolverResource();
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return CREATE_RESOURCE(ppapi_->resource_manager(),
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         FakeHostResolverResource,
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         resolver_resource);
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int32_t FakeHostResolverInterface::Resolve(PP_Resource resource,
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           const char* hostname,
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           uint16_t,
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           const PP_HostResolver_Hint* hints,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           PP_CompletionCallback callback) {
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeHostResolverResource* resolver =
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ppapi_->resource_manager()->Get<FakeHostResolverResource>(resource);
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resolver->resolved = false;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  resolver->hints = *hints;
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!fake_hostname.empty() && fake_hostname == hostname) {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    resolver->resolved = true;
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return RunCompletionCallback(&callback, PP_OK);
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return RunCompletionCallback(&callback, PP_ERROR_NAME_NOT_RESOLVED);
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PP_Var FakeHostResolverInterface::GetCanonicalName(PP_Resource resource) {
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeHostResolverResource* res =
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ppapi_->resource_manager()->Get<FakeHostResolverResource>(resource);
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!res->resolved)
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return PP_Var();
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return ppapi_->GetVarInterface()->VarFromUtf8(fake_hostname.data(),
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                fake_hostname.length());
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)uint32_t FakeHostResolverInterface::GetNetAddressCount(PP_Resource resolver) {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeHostResolverResource* res =
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ppapi_->resource_manager()->Get<FakeHostResolverResource>(resolver);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!res->resolved)
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0;
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  uint32_t rtn = 0;
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (res->hints.family == PP_NETADDRESS_FAMILY_IPV6 ||
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      res->hints.family == PP_NETADDRESS_FAMILY_UNSPECIFIED)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rtn += fake_addresses_v6.size();
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (res->hints.family == PP_NETADDRESS_FAMILY_IPV4 ||
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      res->hints.family == PP_NETADDRESS_FAMILY_UNSPECIFIED)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    rtn += fake_addresses_v4.size();
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return rtn;
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)PP_Resource FakeHostResolverInterface::GetNetAddress(PP_Resource resource,
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                                     uint32_t index) {
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FakeHostResolverResource* res =
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ppapi_->resource_manager()->Get<FakeHostResolverResource>(resource);
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!res->resolved)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0;
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool include_v4 = false;
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int max_index = 0;
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  switch (res->hints.family) {
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case PP_NETADDRESS_FAMILY_IPV4:
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      max_index = fake_addresses_v4.size();
1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      include_v4 = true;
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case PP_NETADDRESS_FAMILY_IPV6:
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      max_index = fake_addresses_v6.size();
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case PP_NETADDRESS_FAMILY_UNSPECIFIED:
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      include_v4 = true;
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      max_index = fake_addresses_v4.size() + fake_addresses_v6.size();
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      break;
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    default:
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return 0;
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (index >= max_index)
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return 0;
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  nacl_io::NetAddressInterface* iface = ppapi_->GetNetAddressInterface();
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Create a new NetAddress resource and return it.
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (include_v4 && index < fake_addresses_v4.size()) {
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_NetAddress_IPv4 addr;
1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sockaddr_in& addr4 = fake_addresses_v4[index];
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    memcpy(addr.addr, &addr4.sin_addr, sizeof(addr4.sin_addr));
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return iface->CreateFromIPv4Address(ppapi_->GetInstance(), &addr);
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  } else {
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (include_v4)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      index -= fake_addresses_v4.size();
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    PP_NetAddress_IPv6 addr;
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    sockaddr_in6& addr6 = fake_addresses_v6[index];
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    memcpy(addr.addr, &addr6.sin6_addr, sizeof(addr6.sin6_addr));
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return iface->CreateFromIPv6Address(ppapi_->GetInstance(), &addr);
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
137