fake_host_resolver_interface.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "fake_ppapi/fake_host_resolver_interface.h"
6
7#include <netinet/in.h>
8
9#include "fake_ppapi/fake_pepper_interface.h"
10#include "fake_ppapi/fake_resource_manager.h"
11#include "fake_ppapi/fake_var_manager.h"
12#include "gtest/gtest.h"
13
14namespace  {
15
16class FakeHostResolverResource : public FakeResource {
17 public:
18  FakeHostResolverResource() : resolved(false) {}
19  static const char* classname() { return "FakeHostResolverResource"; }
20
21  bool resolved;
22  PP_HostResolver_Hint hints;
23};
24
25int32_t RunCompletionCallback(PP_CompletionCallback* callback, int32_t result) {
26  if (callback->func) {
27    PP_RunCompletionCallback(callback, result);
28    return PP_OK_COMPLETIONPENDING;
29  }
30  return result;
31}
32
33}
34
35FakeHostResolverInterface::FakeHostResolverInterface(FakePepperInterface* ppapi)
36    : ppapi_(ppapi) {}
37
38PP_Resource FakeHostResolverInterface::Create(PP_Instance instance) {
39  if (instance != ppapi_->GetInstance())
40    return PP_ERROR_BADRESOURCE;
41
42  FakeHostResolverResource* resolver_resource = new FakeHostResolverResource();
43
44  return CREATE_RESOURCE(ppapi_->resource_manager(),
45                         FakeHostResolverResource,
46                         resolver_resource);
47}
48
49int32_t FakeHostResolverInterface::Resolve(PP_Resource resource,
50                                           const char* hostname,
51                                           uint16_t,
52                                           const PP_HostResolver_Hint* hints,
53                                           PP_CompletionCallback callback) {
54  FakeHostResolverResource* resolver =
55      ppapi_->resource_manager()->Get<FakeHostResolverResource>(resource);
56  resolver->resolved = false;
57  resolver->hints = *hints;
58  if (!fake_hostname.empty() && fake_hostname == hostname) {
59    resolver->resolved = true;
60    return RunCompletionCallback(&callback, PP_OK);
61  }
62  return RunCompletionCallback(&callback, PP_ERROR_NAME_NOT_RESOLVED);
63}
64
65PP_Var FakeHostResolverInterface::GetCanonicalName(PP_Resource resource) {
66  FakeHostResolverResource* res =
67      ppapi_->resource_manager()->Get<FakeHostResolverResource>(resource);
68  if (!res->resolved)
69    return PP_Var();
70  return ppapi_->GetVarInterface()->VarFromUtf8(fake_hostname.data(),
71                                                fake_hostname.length());
72}
73
74uint32_t FakeHostResolverInterface::GetNetAddressCount(PP_Resource resolver) {
75  FakeHostResolverResource* res =
76      ppapi_->resource_manager()->Get<FakeHostResolverResource>(resolver);
77  if (!res->resolved)
78    return 0;
79
80  uint32_t rtn = 0;
81  if (res->hints.family == PP_NETADDRESS_FAMILY_IPV6 ||
82      res->hints.family == PP_NETADDRESS_FAMILY_UNSPECIFIED)
83    rtn += fake_addresses_v6.size();
84
85  if (res->hints.family == PP_NETADDRESS_FAMILY_IPV4 ||
86      res->hints.family == PP_NETADDRESS_FAMILY_UNSPECIFIED)
87    rtn += fake_addresses_v4.size();
88
89  return rtn;
90}
91
92PP_Resource FakeHostResolverInterface::GetNetAddress(PP_Resource resource,
93                                                     uint32_t index) {
94  FakeHostResolverResource* res =
95      ppapi_->resource_manager()->Get<FakeHostResolverResource>(resource);
96  if (!res->resolved)
97    return 0;
98
99  bool include_v4 = false;
100  int max_index = 0;
101  switch (res->hints.family) {
102    case PP_NETADDRESS_FAMILY_IPV4:
103      max_index = fake_addresses_v4.size();
104      include_v4 = true;
105      break;
106    case PP_NETADDRESS_FAMILY_IPV6:
107      max_index = fake_addresses_v6.size();
108      break;
109    case PP_NETADDRESS_FAMILY_UNSPECIFIED:
110      include_v4 = true;
111      max_index = fake_addresses_v4.size() + fake_addresses_v6.size();
112      break;
113    default:
114      return 0;
115  }
116
117  if (index >= max_index)
118    return 0;
119
120  nacl_io::NetAddressInterface* iface = ppapi_->GetNetAddressInterface();
121
122  // Create a new NetAddress resource and return it.
123  if (include_v4 && index < fake_addresses_v4.size()) {
124    PP_NetAddress_IPv4 addr;
125    sockaddr_in& addr4 = fake_addresses_v4[index];
126    memcpy(addr.addr, &addr4.sin_addr, sizeof(addr4.sin_addr));
127    return iface->CreateFromIPv4Address(ppapi_->GetInstance(), &addr);
128  } else {
129    if (include_v4)
130      index -= fake_addresses_v4.size();
131    PP_NetAddress_IPv6 addr;
132    sockaddr_in6& addr6 = fake_addresses_v6[index];
133    memcpy(addr.addr, &addr6.sin6_addr, sizeof(addr6.sin6_addr));
134    return iface->CreateFromIPv6Address(ppapi_->GetInstance(), &addr);
135  }
136}
137