1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/socket/udp_socket.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <algorithm> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/lazy_instance.h" 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/browser/api/api_resource.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/ip_endpoint.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/udp/datagram_socket.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/udp/udp_client_socket.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static base::LazyInstance< 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) BrowserContextKeyedAPIFactory<ApiResourceManager<ResumableUDPSocket> > > 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) g_factory = LAZY_INSTANCE_INITIALIZER; 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)// static 233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)template <> 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)BrowserContextKeyedAPIFactory<ApiResourceManager<ResumableUDPSocket> >* 253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ApiResourceManager<ResumableUDPSocket>::GetFactoryInstance() { 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return g_factory.Pointer(); 273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 283551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UDPSocket::UDPSocket(const std::string& owner_extension_id) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Socket(owner_extension_id), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_(net::DatagramSocket::DEFAULT_BIND, 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::RandIntCallback(), 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL, 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) net::NetLog::Source()) {} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)UDPSocket::~UDPSocket() { Disconnect(); } 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UDPSocket::Connect(const std::string& address, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port, 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback) { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = net::ERR_CONNECTION_FAILED; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_connected_) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPEndPoint ip_end_point; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = net::ERR_ADDRESS_INVALID; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = socket_.Connect(ip_end_point); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_connected_ = (result == net::OK); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (false); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(result); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UDPSocket::Bind(const std::string& address, int port) { 60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (IsBound()) 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return net::ERR_CONNECTION_FAILED; 62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPEndPoint ip_end_point; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_INVALID_ARGUMENT; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return socket_.Bind(ip_end_point); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UDPSocket::Disconnect() { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_connected_ = false; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_.Close(); 738bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) read_callback_.Reset(); 748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) recv_from_callback_.Reset(); 758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) send_to_callback_.Reset(); 768bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) multicast_groups_.clear(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void UDPSocket::Read(int count, const ReadCompletionCallback& callback) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!read_callback_.is_null()) { 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(net::ERR_IO_PENDING, NULL); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_callback_ = callback; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = net::ERR_FAILED; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> io_buffer; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count < 0) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = net::ERR_INVALID_ARGUMENT; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!socket_.is_connected()) { 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = net::ERR_SOCKET_NOT_CONNECTED; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_buffer = new net::IOBuffer(count); 103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result = socket_.Read( 104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) io_buffer.get(), 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) count, 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind( 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &UDPSocket::OnReadComplete, base::Unretained(this), io_buffer)); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (false); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != net::ERR_IO_PENDING) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnReadComplete(io_buffer, result); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UDPSocket::WriteImpl(net::IOBuffer* io_buffer, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int io_buffer_size, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CompletionCallback& callback) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!socket_.is_connected()) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::ERR_SOCKET_NOT_CONNECTED; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return socket_.Write(io_buffer, io_buffer_size, callback); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UDPSocket::RecvFrom(int count, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const RecvFromCompletionCallback& callback) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!recv_from_callback_.is_null()) { 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) callback.Run(net::ERR_IO_PENDING, NULL, std::string(), 0); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recv_from_callback_ = callback; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = net::ERR_FAILED; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<net::IOBuffer> io_buffer; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IPEndPoint> address; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (count < 0) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = net::ERR_INVALID_ARGUMENT; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!socket_.is_connected()) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = net::ERR_SOCKET_NOT_CONNECTED; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_buffer = new net::IOBuffer(count); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) address = new IPEndPoint(); 150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result = socket_.RecvFrom(io_buffer.get(), 151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) count, 152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &address->data, 153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Bind(&UDPSocket::OnRecvFromComplete, 154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Unretained(this), 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) io_buffer, 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) address)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (false); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != net::ERR_IO_PENDING) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnRecvFromComplete(io_buffer, address, result); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UDPSocket::SendTo(scoped_refptr<net::IOBuffer> io_buffer, 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int byte_count, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& address, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!callback.is_null()); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!send_to_callback_.is_null()) { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(penghuang): Put requests in a pending queue to support multiple 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sendTo calls. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) callback.Run(net::ERR_IO_PENDING); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) send_to_callback_ = callback; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = net::ERR_FAILED; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::IPEndPoint ip_end_point; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!StringAndPortToIPEndPoint(address, port, &ip_end_point)) { 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) result = net::ERR_ADDRESS_INVALID; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!socket_.is_connected()) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = net::ERR_SOCKET_NOT_CONNECTED; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = socket_.SendTo( 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_buffer.get(), 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) byte_count, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ip_end_point, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&UDPSocket::OnSendToComplete, base::Unretained(this))); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (false); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != net::ERR_IO_PENDING) 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnSendToComplete(result); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool UDPSocket::IsConnected() { return is_connected_; } 2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UDPSocket::GetPeerAddress(net::IPEndPoint* address) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !socket_.GetPeerAddress(address); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UDPSocket::GetLocalAddress(net::IPEndPoint* address) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !socket_.GetLocalAddress(address); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)Socket::SocketType UDPSocket::GetSocketType() const { return Socket::TYPE_UDP; } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UDPSocket::OnReadComplete(scoped_refptr<net::IOBuffer> io_buffer, 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result) { 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!read_callback_.is_null()); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_callback_.Run(result, io_buffer); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_callback_.Reset(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UDPSocket::OnRecvFromComplete(scoped_refptr<net::IOBuffer> io_buffer, 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<IPEndPoint> address, 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!recv_from_callback_.is_null()); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string ip; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int port = 0; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result > 0 && address.get()) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPEndPointToStringAndPort(address->data, &ip, &port); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recv_from_callback_.Run(result, io_buffer, ip, port); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) recv_from_callback_.Reset(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UDPSocket::OnSendToComplete(int result) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!send_to_callback_.is_null()); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) send_to_callback_.Run(result); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) send_to_callback_.Reset(); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 241a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool UDPSocket::IsBound() { return socket_.is_connected(); } 242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int UDPSocket::JoinGroup(const std::string& address) { 244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::IPAddressNumber ip; 245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!net::ParseIPLiteralToNumber(address, &ip)) 246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::ERR_ADDRESS_INVALID; 247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string normalized_address = net::IPAddressToString(ip); 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string>::iterator find_result = std::find( 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) multicast_groups_.begin(), multicast_groups_.end(), normalized_address); 251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (find_result != multicast_groups_.end()) 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::ERR_ADDRESS_INVALID; 253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int rv = socket_.JoinGroup(ip); 255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv == 0) 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) multicast_groups_.push_back(normalized_address); 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return rv; 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int UDPSocket::LeaveGroup(const std::string& address) { 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::IPAddressNumber ip; 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!net::ParseIPLiteralToNumber(address, &ip)) 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::ERR_ADDRESS_INVALID; 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string normalized_address = net::IPAddressToString(ip); 266a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<std::string>::iterator find_result = std::find( 267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) multicast_groups_.begin(), multicast_groups_.end(), normalized_address); 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (find_result == multicast_groups_.end()) 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::ERR_ADDRESS_INVALID; 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int rv = socket_.LeaveGroup(ip); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (rv == 0) 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) multicast_groups_.erase(find_result); 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return rv; 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int UDPSocket::SetMulticastTimeToLive(int ttl) { 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return socket_.SetMulticastTimeToLive(ttl); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int UDPSocket::SetMulticastLoopbackMode(bool loopback) { 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return socket_.SetMulticastLoopbackMode(loopback); 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const std::vector<std::string>& UDPSocket::GetJoinedGroups() const { 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return multicast_groups_; 287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ResumableUDPSocket::ResumableUDPSocket(const std::string& owner_extension_id) 2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : UDPSocket(owner_extension_id), 2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) persistent_(false), 292a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) buffer_size_(0), 293a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) paused_(false) {} 2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 295a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ResumableUDPSocket::IsPersistent() const { return persistent(); } 2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 298