17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file. 47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/tests/test_udp_socket.h" 67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include <vector> 87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/cpp/pass_ref.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/cpp/tcp_socket.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ppapi/cpp/udp_socket.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/cpp/var.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/tests/test_utils.h" 147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ppapi/tests/testing_instance.h" 157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)REGISTER_TEST_CASE(UDPSocket); 177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)namespace { 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const uint16_t kPortScanFrom = 1024; 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const uint16_t kPortScanTo = 4096; 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochpp::NetAddress ReplacePort(const pp::InstanceHandle& instance, 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const pp::NetAddress& addr, 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch uint16_t port) { 267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) switch (addr.GetFamily()) { 277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case PP_NETADDRESS_FAMILY_IPV4: { 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_NetAddress_IPv4 ipv4_addr; 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!addr.DescribeAsIPv4Address(&ipv4_addr)) 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ipv4_addr.port = ConvertToNetEndian16(port); 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return pp::NetAddress(instance, ipv4_addr); 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) case PP_NETADDRESS_FAMILY_IPV6: { 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_NetAddress_IPv6 ipv6_addr; 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!addr.DescribeAsIPv6Address(&ipv6_addr)) 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ipv6_addr.port = ConvertToNetEndian16(port); 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return pp::NetAddress(instance, ipv6_addr); 407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) default: { 427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_NOTREACHED(); 437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return pp::NetAddress(); 467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} // namespace 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)TestUDPSocket::TestUDPSocket(TestingInstance* instance) : TestCase(instance) { 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool TestUDPSocket::Init() { 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool tcp_socket_is_available = pp::TCPSocket::IsAvailable(); 557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!tcp_socket_is_available) 567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) instance_->AppendError("PPB_TCPSocket interface not available"); 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool udp_socket_is_available = pp::UDPSocket::IsAvailable(); 597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!udp_socket_is_available) 607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) instance_->AppendError("PPB_UDPSocket interface not available"); 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool net_address_is_available = pp::NetAddress::IsAvailable(); 637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!net_address_is_available) 647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) instance_->AppendError("PPB_NetAddress interface not available"); 657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string host; 677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) uint16_t port = 0; 687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool init_address = 697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) GetLocalHostPort(instance_->pp_instance(), &host, &port) && 707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ResolveHost(instance_->pp_instance(), host, port, &address_); 717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!init_address) 727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) instance_->AppendError("Can't init address"); 737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return tcp_socket_is_available && 757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) udp_socket_is_available && 767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) net_address_is_available && 777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) init_address && 787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CheckTestingInterface() && 797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) EnsureRunningOverHTTP(); 807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TestUDPSocket::RunTests(const std::string& filter) { 837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RUN_CALLBACK_TEST(TestUDPSocket, ReadWrite, filter); 847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RUN_CALLBACK_TEST(TestUDPSocket, Broadcast, filter); 857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RUN_CALLBACK_TEST(TestUDPSocket, SetOption, filter); 867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string TestUDPSocket::GetLocalAddress(pp::NetAddress* address) { 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::TCPSocket socket(instance_); 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback.WaitForResult(socket.Connect(address_, callback.GetCallback())); 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback); 937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *address = socket.GetLocalAddress(); 957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_NE(0, address->pp_resource()); 967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) socket.Close(); 977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string TestUDPSocket::SetBroadcastOptions(pp::UDPSocket* socket) { 1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TestCompletionCallback callback_1(instance_->pp_instance(), callback_type()); 1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback_1.WaitForResult(socket->SetOption( 1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_UDPSOCKET_OPTION_ADDRESS_REUSE, pp::Var(true), 1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback_1.GetCallback())); 1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback_1); 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(PP_OK, callback_1.result()); 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TestCompletionCallback callback_2(instance_->pp_instance(), callback_type()); 1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback_2.WaitForResult(socket->SetOption( 1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_UDPSOCKET_OPTION_BROADCAST, pp::Var(true), callback_2.GetCallback())); 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback_2); 1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(PP_OK, callback_2.result()); 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string TestUDPSocket::BindUDPSocket(pp::UDPSocket* socket, 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const pp::NetAddress& address) { 1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback.WaitForResult(socket->Bind(address, callback.GetCallback())); 1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback); 1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(PP_OK, callback.result()); 1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string TestUDPSocket::LookupPortAndBindUDPSocket( 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::UDPSocket* socket, 128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress* address) { 129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress base_address; 1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(GetLocalAddress(&base_address)); 1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) bool is_free_port_found = false; 1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (uint16_t port = kPortScanFrom; port < kPortScanTo; ++port) { 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress new_address = ReplacePort(instance_, base_address, port); 1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_NE(0, new_address.pp_resource()); 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (BindUDPSocket(socket, new_address).empty()) { 1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) is_free_port_found = true; 1387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) break; 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 1417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!is_free_port_found) 1427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return "Can't find available port"; 1437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *address = socket->GetBoundAddress(); 1457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_NE(0, address->pp_resource()); 1467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string TestUDPSocket::ReadSocket(pp::UDPSocket* socket, 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress* address, 1527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) size_t size, 1537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string* message) { 1547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::vector<char> buffer(size); 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch TestCompletionCallbackWithOutput<pp::NetAddress> callback( 1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) instance_->pp_instance(), callback_type()); 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback.WaitForResult( 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) socket->RecvFrom(&buffer[0], size, callback.GetCallback())); 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback); 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_FALSE(callback.result() < 0); 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(size, static_cast<size_t>(callback.result())); 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) *address = callback.output(); 1637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) message->assign(buffer.begin(), buffer.end()); 1647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 1657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstd::string TestUDPSocket::PassMessage(pp::UDPSocket* target, 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::UDPSocket* source, 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const pp::NetAddress& target_address, 1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& message, 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress* recvfrom_address) { 1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 1737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) int32_t rv = source->SendTo(message.c_str(), message.size(), 1747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) target_address, 1757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback.GetCallback()); 1767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string str; 1777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(ReadSocket(target, recvfrom_address, message.size(), 1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &str)); 1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback.WaitForResult(rv); 1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback); 1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_FALSE(callback.result() < 0); 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(message.size(), static_cast<size_t>(callback.result())); 1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(message, str); 1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string TestUDPSocket::TestReadWrite() { 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::UDPSocket server_socket(instance_), client_socket(instance_); 190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress server_address, client_address; 1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&server_socket, 1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &server_address)); 1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&client_socket, 1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &client_address)); 1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string message = "Simple message that will be sent via UDP"; 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress recvfrom_address; 1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(PassMessage(&server_socket, &client_socket, 1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) server_address, message, 2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &recvfrom_address)); 2017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(EqualNetAddress(recvfrom_address, client_address)); 2027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) server_socket.Close(); 2047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) client_socket.Close(); 2057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (server_socket.GetBoundAddress().pp_resource() != 0) 2077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return "PPB_UDPSocket::GetBoundAddress: expected failure"; 2087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 2107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string TestUDPSocket::TestBroadcast() { 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::UDPSocket server1(instance_), server2(instance_); 2147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server1)); 2167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&server2)); 2177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_NetAddress_IPv4 any_ipv4_address = { 0, { 0, 0, 0, 0 } }; 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress any_address(instance_, any_ipv4_address); 2207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server1, any_address)); 2217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Fill port field of |server_address|. 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress server_address = server1.GetBoundAddress(); 2237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_NE(0, server_address.pp_resource()); 2247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(BindUDPSocket(&server2, server_address)); 2257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_NetAddress_IPv4 server_ipv4_address; 2277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(server_address.DescribeAsIPv4Address(&server_ipv4_address)); 2287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_NetAddress_IPv4 broadcast_ipv4_address = { 2307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) server_ipv4_address.port, { 0xff, 0xff, 0xff, 0xff } 2317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) }; 232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress broadcast_address(instance_, broadcast_ipv4_address); 2337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string message; 2357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string first_message = "first message"; 2367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string second_message = "second_message"; 2377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress recvfrom_address; 2397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(PassMessage(&server1, &server2, broadcast_address, 2407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) first_message, &recvfrom_address)); 2417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |first_message| was also received by |server2|. 2427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(ReadSocket(&server2, &recvfrom_address, 2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) first_message.size(), &message)); 2447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(first_message, message); 2457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(PassMessage(&server2, &server1, broadcast_address, 2477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) second_message, &recvfrom_address)); 2487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // |second_message| was also received by |server1|. 2497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(ReadSocket(&server1, &recvfrom_address, 2507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) second_message.size(), &message)); 2517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(second_message, message); 2527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) server1.Close(); 2547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) server2.Close(); 2557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 2567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)std::string TestUDPSocket::TestSetOption() { 259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::UDPSocket socket(instance_); 2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_SUBTEST_SUCCESS(SetBroadcastOptions(&socket)); 2627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 2637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) // Try to pass incorrect option value's type. 2647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TestCompletionCallback callback(instance_->pp_instance(), callback_type()); 2657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) callback.WaitForResult(socket.SetOption( 2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PP_UDPSOCKET_OPTION_ADDRESS_REUSE, pp::Var(1), callback.GetCallback())); 2677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) CHECK_CALLBACK_BEHAVIOR(callback); 2687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_EQ(PP_ERROR_BADARGUMENT, callback.result()); 2697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.WaitForResult(socket.SetOption( 271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_UDPSOCKET_OPTION_BROADCAST, pp::Var(false), callback.GetCallback())); 272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK_CALLBACK_BEHAVIOR(callback); 273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(PP_OK, callback.result()); 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // SEND_BUFFER_SIZE and RECV_BUFFER_SIZE shouldn't be set before the socket is 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // bound. 277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.WaitForResult(socket.SetOption( 278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE, pp::Var(4096), 279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.GetCallback())); 280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK_CALLBACK_BEHAVIOR(callback); 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(PP_ERROR_FAILED, callback.result()); 282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.WaitForResult(socket.SetOption( 284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE, pp::Var(512), 285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.GetCallback())); 286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK_CALLBACK_BEHAVIOR(callback); 287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(PP_ERROR_FAILED, callback.result()); 288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pp::NetAddress address; 290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_SUBTEST_SUCCESS(LookupPortAndBindUDPSocket(&socket, &address)); 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // ADDRESS_REUSE and BROADCAST won't take effect after the socket is bound. 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.WaitForResult(socket.SetOption( 294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_UDPSOCKET_OPTION_ADDRESS_REUSE, pp::Var(true), 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.GetCallback())); 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK_CALLBACK_BEHAVIOR(callback); 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(PP_ERROR_FAILED, callback.result()); 298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.WaitForResult(socket.SetOption( 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_UDPSOCKET_OPTION_BROADCAST, pp::Var(true), callback.GetCallback())); 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK_CALLBACK_BEHAVIOR(callback); 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(PP_ERROR_FAILED, callback.result()); 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // SEND_BUFFER_SIZE and RECV_BUFFER_SIZE can be set after the socket is bound. 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.WaitForResult(socket.SetOption( 306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE, pp::Var(2048), 307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.GetCallback())); 308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK_CALLBACK_BEHAVIOR(callback); 309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(PP_OK, callback.result()); 310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.WaitForResult(socket.SetOption( 312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE, pp::Var(1024), 313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch callback.GetCallback())); 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK_CALLBACK_BEHAVIOR(callback); 315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_EQ(PP_OK, callback.result()); 316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) PASS(); 3187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 319