Chromium Code Reviews| Index: content/browser/renderer_host/pepper_message_filter.cc |
| diff --git a/content/browser/renderer_host/pepper_message_filter.cc b/content/browser/renderer_host/pepper_message_filter.cc |
| index f4c2cfce5993a0ce607dec373082088a10982b34..b193cee3439cca122f64c8f8679f5776a845827b 100644 |
| --- a/content/browser/renderer_host/pepper_message_filter.cc |
| +++ b/content/browser/renderer_host/pepper_message_filter.cc |
| @@ -38,6 +38,8 @@ |
| #include "net/socket/client_socket_handle.h" |
| #include "net/socket/ssl_client_socket.h" |
| #include "net/socket/tcp_client_socket.h" |
| +#include "net/udp/udp_server_socket.h" |
| +#include "net/udp/udp_socket.h" |
| #include "net/url_request/url_request_context.h" |
| #include "ppapi/c/private/ppb_flash_net_connector.h" |
| #include "ppapi/proxy/ppapi_messages.h" |
| @@ -115,6 +117,19 @@ bool NetAddressToAddressList(const PP_Flash_NetAddress& net_addr, |
| return true; |
| } |
| +bool NetAddressToIPEndPoint(const PP_Flash_NetAddress& net_addr, |
| + net::IPEndPoint* ip_end_point) { |
| + if (!ip_end_point || !ValidateNetAddress(net_addr)) |
| + return false; |
| + |
| + if (!ip_end_point->FromSockAddr( |
|
viettrungluu
2011/08/29 19:20:05
You should probably refactor NetAddressToAddressLi
mtilburg
2011/08/30 16:56:14
Done.
|
| + reinterpret_cast<const sockaddr*>(net_addr.data), net_addr.size)) { |
| + return false; |
| + } |
| + |
| + return true; |
| +} |
| + |
| } // namespace |
| // Make sure the storage in |PP_Flash_NetAddress| is big enough. (Do it here |
| @@ -498,6 +513,168 @@ bool PepperMessageFilter::FlashTCPSocket::IsConnected() const { |
| connection_state_ == SSL_CONNECTED; |
| } |
| +class PepperMessageFilter::FlashUDPSocket { |
| + public: |
| + FlashUDPSocket(PepperMessageFilter* pepper_message_filter, |
| + int32 routing_id, |
| + uint32 plugin_dispatcher_id, |
| + int32_t family, |
| + uint32 socket_id); |
| + ~FlashUDPSocket(); |
| + |
| + void Bind(const PP_Flash_NetAddress &addr); |
| + void RecvFrom(int32_t num_bytes, |
| + const PP_Flash_NetAddress &addr); |
|
viettrungluu
2011/08/29 19:20:05
Nits:
- indentation,
- '&' should be attached to t
mtilburg
2011/08/30 16:56:14
Done.
|
| + void SendTo(const std::string& data, |
| + const PP_Flash_NetAddress &addr); |
|
viettrungluu
2011/08/29 19:20:05
"
mtilburg
2011/08/30 16:56:14
Done.
|
| + |
| + private: |
| + |
|
viettrungluu
2011/08/29 19:20:05
Nit: no blank line here.
mtilburg
2011/08/30 16:56:14
Done.
|
| + void SendRecvFromACKError(); |
| + void SendSendToACKError(); |
| + |
| + void OnRecvFromCompleted(int result); |
| + void OnSendToCompleted(int result); |
| + |
| + PepperMessageFilter* pepper_message_filter_; |
| + int32 routing_id_; |
| + uint32 plugin_dispatcher_id_; |
| + int32_t family_; |
| + uint32 socket_id_; |
| + |
| + net::CompletionCallbackImpl<FlashUDPSocket> recvfrom_callback_; |
| + net::CompletionCallbackImpl<FlashUDPSocket> sendto_callback_; |
| + |
| + scoped_ptr<net::UDPServerSocket> socket_; |
| + |
| + scoped_refptr<net::IOBuffer> recvfrom_buffer_; |
| + scoped_refptr<net::IOBuffer> sendto_buffer_; |
| + |
| + net::IPEndPoint recvfrom_address_; |
| + net::CompletionCallback* read_callback_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(FlashUDPSocket); |
| +}; |
| + |
| +PepperMessageFilter::FlashUDPSocket::FlashUDPSocket( |
| + PepperMessageFilter* pepper_message_filter, |
| + int32 routing_id, |
| + uint32 plugin_dispatcher_id, |
| + int32_t family, |
| + uint32 socket_id) |
| + : pepper_message_filter_(pepper_message_filter), |
| + routing_id_(routing_id), |
| + plugin_dispatcher_id_(plugin_dispatcher_id), |
| + family_(family), |
| + socket_id_(socket_id), |
| + ALLOW_THIS_IN_INITIALIZER_LIST( |
| + recvfrom_callback_(this, &FlashUDPSocket::OnRecvFromCompleted)), |
| + ALLOW_THIS_IN_INITIALIZER_LIST( |
| + sendto_callback_(this, &FlashUDPSocket::OnSendToCompleted)) { |
| + DCHECK(pepper_message_filter); |
| +} |
| + |
| +PepperMessageFilter::FlashUDPSocket::~FlashUDPSocket() { |
| + // Make sure no further callbacks from socket_. |
| + if (socket_.get()) { |
| + socket_->Close(); |
| + } |
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocket::Bind( |
| + const PP_Flash_NetAddress &addr) { |
| + socket_.reset( |
| + new net::UDPServerSocket(NULL, net::NetLog::Source())); |
|
viettrungluu
2011/08/29 19:20:05
Nit: I believe this all fits on one (80-column) li
mtilburg
2011/08/30 16:56:14
Done.
|
| + |
| + net::IPEndPoint address; |
| + NetAddressToIPEndPoint(addr, &address); |
|
viettrungluu
2011/08/29 19:20:05
You should check the return value.
mtilburg
2011/08/30 16:56:14
Done.
|
| + |
| + // Calls ::bind on the address... |
| + // TODO(mtilburg): handle return value?? |
|
viettrungluu
2011/08/29 19:20:05
Yes you should.
mtilburg
2011/08/30 16:56:14
Done.
|
| + socket_->Listen(address); |
| + |
| + // TODO(mtilburg): send ACK Message |
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocket::RecvFrom( |
| + int32_t num_bytes, |
| + const PP_Flash_NetAddress &addr){ |
| + if (recvfrom_buffer_.get() ){ |
| + SendRecvFromACKError(); |
|
viettrungluu
2011/08/29 19:20:05
Nit: indentation.
mtilburg
2011/08/30 16:56:14
Done.
|
| + return; |
| + } |
| + |
| + recvfrom_buffer_ = new net::IOBuffer(1024); |
| + int result = socket_->RecvFrom(recvfrom_buffer_, |
| + num_bytes, |
| + &recvfrom_address_, |
| + &recvfrom_callback_); |
| + |
|
viettrungluu
2011/08/29 19:20:05
Nit: remove extra blank line.
mtilburg
2011/08/30 16:56:14
Done.
|
| + |
| + if (result != net::ERR_IO_PENDING) |
| + OnRecvFromCompleted(result); |
|
viettrungluu
2011/08/29 19:20:05
Nit: indentation.
mtilburg
2011/08/30 16:56:14
Done.
|
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocket::SendTo( |
| + const std::string& data, |
| + const PP_Flash_NetAddress &addr){ |
| + |
|
viettrungluu
2011/08/29 19:20:05
Nit: no blank line here.
mtilburg
2011/08/30 16:56:14
Done.
|
| + if( sendto_buffer_.get() || data.empty()){ |
| + SendSendToACKError(); |
| + return; |
| + } |
| + |
| + net::IPEndPoint address; |
| + NetAddressToIPEndPoint(addr, &address); |
|
viettrungluu
2011/08/29 19:20:05
Check return value.
mtilburg
2011/08/30 16:56:14
Done.
|
| + |
| + int data_size = data.size(); |
| + |
| + sendto_buffer_ = new net::IOBuffer(data_size); |
| + memcpy(sendto_buffer_->data(), data.c_str(), data.size()); |
|
viettrungluu
2011/08/29 19:20:05
data.data(), not data.c_str()
mtilburg
2011/08/30 16:56:14
Done.
|
| + int result = socket_->SendTo(sendto_buffer_, |
| + data.size(), |
| + address, |
| + &sendto_callback_); |
| + |
| + if (result != net::ERR_IO_PENDING) |
| + OnSendToCompleted(result); |
|
viettrungluu
2011/08/29 19:20:05
Nit: indentation.
mtilburg
2011/08/30 16:56:14
Done.
|
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocket::SendRecvFromACKError() { |
| + PP_Flash_NetAddress addr = kInvalidNetAddress; |
| + pepper_message_filter_->Send( |
| + new PpapiMsg_PPBFlashUDPSocket_RecvFromACK( |
| + routing_id_, plugin_dispatcher_id_, socket_id_, false, |
| + std::string(), addr)); |
| +} |
| +void PepperMessageFilter::FlashUDPSocket::SendSendToACKError() { |
| + pepper_message_filter_->Send( |
| + new PpapiMsg_PPBFlashUDPSocket_SendToACK( |
| + routing_id_, plugin_dispatcher_id_, socket_id_, false, 0)); |
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocket::OnRecvFromCompleted(int result) { |
| + DCHECK(recvfrom_buffer_.get()); |
| + |
| + // convert the IPEndPointAddress we get back from RecvFrom to |
|
viettrungluu
2011/08/29 19:20:05
Nit: capitalization and punctuation.
mtilburg
2011/08/30 16:56:14
Done.
|
| + // a PP_Flash_NetAddress, to send back to Flash |
| + PP_Flash_NetAddress addr = kInvalidNetAddress; |
| + IPEndPointToNetAddress(recvfrom_address_, &addr ); |
|
viettrungluu
2011/08/29 19:20:05
Again, return value.
Also, no space before ')'.
mtilburg
2011/08/30 16:56:14
Done.
|
| + |
| + pepper_message_filter_->Send( |
| + new PpapiMsg_PPBFlashUDPSocket_RecvFromACK( |
| + routing_id_, plugin_dispatcher_id_, socket_id_, true, |
| + std::string(recvfrom_buffer_->data(), result), addr)); |
|
viettrungluu
2011/08/29 19:20:05
What if result < 0?
mtilburg
2011/08/30 16:56:14
Done.
|
| + |
| + recvfrom_buffer_ = NULL; |
|
viettrungluu
2011/08/29 19:20:05
|recvfrom_buffer_.reset();| would probably be more
mtilburg
2011/08/30 16:56:14
I get this error:
content/browser/renderer_host/p
|
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocket::OnSendToCompleted(int result){ |
| + pepper_message_filter_->Send( |
| + new PpapiMsg_PPBFlashUDPSocket_SendToACK( |
| + routing_id_, plugin_dispatcher_id_, socket_id_, true, result)); |
| +} |
| + |
| PepperMessageFilter::FlashTCPSocketManager::FlashTCPSocketManager( |
| PepperMessageFilter* pepper_message_filter) |
| : next_socket_id_(1), |
| @@ -617,12 +794,126 @@ PepperMessageFilter::FlashTCPSocketManager::GetCertVerifier() { |
| return cert_verifier_.get(); |
| } |
| +// FlashUDPSocketManager manages the mapping from socket IDs to FlashTCPSocket |
| +// instances |
|
viettrungluu
2011/08/29 19:20:05
punctuation
mtilburg
2011/08/30 16:56:14
Done.
|
| +class PepperMessageFilter::FlashUDPSocketManager { |
|
viettrungluu
2011/08/29 19:20:05
Please refactor so that the TCP and UDP socket man
mtilburg
2011/08/30 16:56:14
still working on this one...
mtilburg
2011/09/06 22:06:58
Done.
|
| + public: |
| + explicit FlashUDPSocketManager(PepperMessageFilter* pepper_message_filter); |
| + |
| + void OnMsgCreate(int32 routing_id, |
| + uint32 plugin_dispatcher_id, |
| + int32_t family, |
| + uint32* socket_id); |
| + void OnMsgBind(uint32 socket_id, |
| + const PP_Flash_NetAddress &addr); |
| + void OnMsgRecvFrom(uint32 socket_id, |
| + int32_t num_bytes, |
| + const PP_Flash_NetAddress &addr); |
| + void OnMsgSendTo(uint32 socket_id, |
| + const std::string& data, |
| + const PP_Flash_NetAddress &addr); |
| + void OnMsgDisconnect(uint32 socket_id); |
| + |
| + private: |
| + typedef std::map<uint32, linked_ptr<FlashUDPSocket> > SocketMap; |
| + SocketMap sockets_; |
| + |
| + uint32 next_socket_id_; |
| + |
| + PepperMessageFilter* pepper_message_filter_; |
| + DISALLOW_COPY_AND_ASSIGN(FlashUDPSocketManager); |
| +}; |
| + |
| +PepperMessageFilter::FlashUDPSocketManager::FlashUDPSocketManager( |
| + PepperMessageFilter* pepper_message_filter) |
| + : next_socket_id_(1), |
| + pepper_message_filter_(pepper_message_filter) { |
| + DCHECK(pepper_message_filter); |
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocketManager::OnMsgCreate( |
| + int32 routing_id, |
| + uint32 plugin_dispatcher_id, |
| + int32_t family, |
| + uint32* socket_id) { |
| + |
| + DCHECK(socket_id); |
| + if (sockets_.size() >= std::numeric_limits<uint32>::max()) { |
| + // All valid IDs are being used. |
| + *socket_id = 0; |
| + return; |
| + } |
| + do { |
| + // Although it is unlikely, make sure that we won't cause any trouble when |
| + // the counter overflows. |
| + *socket_id = next_socket_id_++; |
| + } while (*socket_id == 0 || |
| + sockets_.find(*socket_id) != sockets_.end()); |
| + sockets_[*socket_id] = linked_ptr<FlashUDPSocket>( |
| + new FlashUDPSocket(pepper_message_filter_, routing_id, |
| + plugin_dispatcher_id, family, *socket_id)); |
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocketManager::OnMsgBind( |
| + uint32 socket_id, |
| + const PP_Flash_NetAddress& addr) { |
| + SocketMap::iterator iter = sockets_.find(socket_id); |
| + if (iter == sockets_.end()) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + iter->second->Bind(addr); |
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocketManager::OnMsgRecvFrom( |
| + uint32 socket_id, |
| + int32_t num_bytes, |
| + const PP_Flash_NetAddress &addr) { |
| + SocketMap::iterator iter = sockets_.find(socket_id); |
| + if (iter == sockets_.end()) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + iter->second->RecvFrom(num_bytes, addr); |
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocketManager::OnMsgSendTo( |
| + uint32 socket_id, |
| + const std::string& data, |
| + const PP_Flash_NetAddress &addr){ |
| + SocketMap::iterator iter = sockets_.find(socket_id); |
| + if (iter == sockets_.end()) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + iter->second->SendTo(data, addr); |
| +} |
| + |
| +void PepperMessageFilter::FlashUDPSocketManager::OnMsgDisconnect( |
| + uint32 socket_id) { |
| + SocketMap::iterator iter = sockets_.find(socket_id); |
| + if (iter == sockets_.end()) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + // Destroy the FlashTCPSocket instance will cancel any pending completion |
| + // callback. From this point on, there won't be any messages associated with |
| + // this socket sent to the plugin side. |
| + sockets_.erase(iter); |
| +} |
| + |
| PepperMessageFilter::PepperMessageFilter( |
| const content::ResourceContext* resource_context) |
| : resource_context_(resource_context), |
| host_resolver_(NULL), |
| ALLOW_THIS_IN_INITIALIZER_LIST( |
| - socket_manager_(new FlashTCPSocketManager(this))) { |
| + socket_manager_(new FlashTCPSocketManager(this))), |
| + ALLOW_THIS_IN_INITIALIZER_LIST( |
| + socket_manager_udp_(new FlashUDPSocketManager(this))) { |
| DCHECK(resource_context_); |
| } |
| @@ -630,7 +921,9 @@ PepperMessageFilter::PepperMessageFilter(net::HostResolver* host_resolver) |
| : resource_context_(NULL), |
| host_resolver_(host_resolver), |
| ALLOW_THIS_IN_INITIALIZER_LIST( |
| - socket_manager_(new FlashTCPSocketManager(this))) { |
| + socket_manager_(new FlashTCPSocketManager(this))), |
| + ALLOW_THIS_IN_INITIALIZER_LIST( |
| + socket_manager_udp_(new FlashUDPSocketManager(this))) { |
| DCHECK(host_resolver); |
| } |
| @@ -671,6 +964,24 @@ bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg, |
| IPC_MESSAGE_FORWARD( |
| PpapiHostMsg_PPBFlashTCPSocket_Disconnect, |
| socket_manager_.get(), FlashTCPSocketManager::OnMsgDisconnect) |
| + |
| + // UDP |
| + IPC_MESSAGE_FORWARD( |
| + PpapiHostMsg_PPBFlashUDPSocket_Create, |
| + socket_manager_udp_.get(), FlashUDPSocketManager::OnMsgCreate) |
| + IPC_MESSAGE_FORWARD( |
| + PpapiHostMsg_PPBFlashUDPSocket_Bind, |
| + socket_manager_udp_.get(), FlashUDPSocketManager::OnMsgBind) |
| + IPC_MESSAGE_FORWARD( |
| + PpapiHostMsg_PPBFlashUDPSocket_RecvFrom, |
| + socket_manager_udp_.get(), FlashUDPSocketManager::OnMsgRecvFrom) |
| + IPC_MESSAGE_FORWARD( |
| + PpapiHostMsg_PPBFlashUDPSocket_SendTo, |
| + socket_manager_udp_.get(), FlashUDPSocketManager::OnMsgSendTo) |
| + IPC_MESSAGE_FORWARD( |
| + PpapiHostMsg_PPBFlashUDPSocket_Disconnect, |
| + socket_manager_udp_.get(), FlashUDPSocketManager::OnMsgDisconnect) |
| + |
| IPC_MESSAGE_UNHANDLED(handled = false) |
| IPC_END_MESSAGE_MAP_EX() |
| return handled; |