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; |