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
14 namespace {
15
16 class FakeHostResolverResource : public FakeResource {
17 public:
FakeHostResolverResource()18 FakeHostResolverResource() : resolved(false) {}
classname()19 static const char* classname() { return "FakeHostResolverResource"; }
20
21 bool resolved;
22 PP_HostResolver_Hint hints;
23 };
24
RunCompletionCallback(PP_CompletionCallback * callback,int32_t result)25 int32_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
FakeHostResolverInterface(FakePepperInterface * ppapi)35 FakeHostResolverInterface::FakeHostResolverInterface(FakePepperInterface* ppapi)
36 : ppapi_(ppapi) {}
37
Create(PP_Instance instance)38 PP_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
Resolve(PP_Resource resource,const char * hostname,uint16_t,const PP_HostResolver_Hint * hints,PP_CompletionCallback callback)49 int32_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
GetCanonicalName(PP_Resource resource)65 PP_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
GetNetAddressCount(PP_Resource resolver)74 uint32_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
GetNetAddress(PP_Resource resource,uint32_t index)92 PP_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