diff options
author | reillyg <reillyg@chromium.org> | 2015-04-10 20:47:21 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-11 03:48:05 +0000 |
commit | 92c5e06599547fa733d45f4c000a31acbe0c66f8 (patch) | |
tree | 65d1d37266e4a561c982176db39921fbbd05b7bb | |
parent | 9045adae17d792e3d0c475f90e906de2b29df1e2 (diff) | |
download | chromium_src-92c5e06599547fa733d45f4c000a31acbe0c66f8.zip chromium_src-92c5e06599547fa733d45f4c000a31acbe0c66f8.tar.gz chromium_src-92c5e06599547fa733d45f4c000a31acbe0c66f8.tar.bz2 |
Implement chrome.sockets.udp.setBroadcast.
Enable Chrome Apps to receive broadcast UDP traffic by setting the
SO_BROADCAST option on a socket. This feature piggybacks on existing
permissions as it requires a socket to be bound to the interface where
the broadcast traffic will be received.
BUG=308461
Review URL: https://codereview.chromium.org/1071813002
Cr-Commit-Position: refs/heads/master@{#324768}
-rw-r--r-- | extensions/browser/api/socket/udp_socket.cc | 7 | ||||
-rw-r--r-- | extensions/browser/api/socket/udp_socket.h | 2 | ||||
-rw-r--r-- | extensions/browser/api/sockets_udp/sockets_udp_api.cc | 26 | ||||
-rw-r--r-- | extensions/browser/api/sockets_udp/sockets_udp_api.h | 18 | ||||
-rw-r--r-- | extensions/browser/extension_function_histogram_value.h | 1 | ||||
-rw-r--r-- | extensions/common/api/sockets_udp.idl | 13 | ||||
-rw-r--r-- | extensions/test/data/sockets_udp/api/background.js | 91 | ||||
-rw-r--r-- | tools/metrics/histograms/histograms.xml | 1 |
8 files changed, 158 insertions, 1 deletions
diff --git a/extensions/browser/api/socket/udp_socket.cc b/extensions/browser/api/socket/udp_socket.cc index 42d7bc3..2822046 100644 --- a/extensions/browser/api/socket/udp_socket.cc +++ b/extensions/browser/api/socket/udp_socket.cc @@ -297,6 +297,13 @@ int UDPSocket::SetMulticastLoopbackMode(bool loopback) { return socket_.SetMulticastLoopbackMode(loopback); } +int UDPSocket::SetBroadcast(bool enabled) { + if (!socket_.is_connected()) { + return net::ERR_SOCKET_NOT_CONNECTED; + } + return socket_.SetBroadcast(enabled); +} + const std::vector<std::string>& UDPSocket::GetJoinedGroups() const { return multicast_groups_; } diff --git a/extensions/browser/api/socket/udp_socket.h b/extensions/browser/api/socket/udp_socket.h index 3169960..9b63b2c 100644 --- a/extensions/browser/api/socket/udp_socket.h +++ b/extensions/browser/api/socket/udp_socket.h @@ -45,6 +45,8 @@ class UDPSocket : public Socket { int SetMulticastTimeToLive(int ttl); int SetMulticastLoopbackMode(bool loopback); + int SetBroadcast(bool enabled); + const std::vector<std::string>& GetJoinedGroups() const; protected: diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api.cc b/extensions/browser/api/sockets_udp/sockets_udp_api.cc index b269aa8..5cdcee6 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api.cc +++ b/extensions/browser/api/sockets_udp/sockets_udp_api.cc @@ -506,5 +506,31 @@ void SocketsUdpGetJoinedGroupsFunction::Work() { results_ = sockets_udp::GetJoinedGroups::Results::Create(groups); } +SocketsUdpSetBroadcastFunction::SocketsUdpSetBroadcastFunction() { +} + +SocketsUdpSetBroadcastFunction::~SocketsUdpSetBroadcastFunction() { +} + +bool SocketsUdpSetBroadcastFunction::Prepare() { + params_ = core_api::sockets_udp::SetBroadcast::Params::Create(*args_); + EXTENSION_FUNCTION_VALIDATE(params_.get()); + return true; +} + +void SocketsUdpSetBroadcastFunction::Work() { + ResumableUDPSocket* socket = GetUdpSocket(params_->socket_id); + if (!socket) { + error_ = kSocketNotFoundError; + return; + } + + int net_result = socket->SetBroadcast(params_->enabled); + if (net_result != net::OK) { + error_ = net::ErrorToString(net_result); + } + results_ = sockets_udp::SetBroadcast::Results::Create(net_result); +} + } // namespace core_api } // namespace extensions diff --git a/extensions/browser/api/sockets_udp/sockets_udp_api.h b/extensions/browser/api/sockets_udp/sockets_udp_api.h index 20fd7e6..2df2dbc1 100644 --- a/extensions/browser/api/sockets_udp/sockets_udp_api.h +++ b/extensions/browser/api/sockets_udp/sockets_udp_api.h @@ -273,6 +273,24 @@ class SocketsUdpGetJoinedGroupsFunction : public UDPSocketAsyncApiFunction { scoped_ptr<sockets_udp::GetJoinedGroups::Params> params_; }; +class SocketsUdpSetBroadcastFunction : public UDPSocketAsyncApiFunction { + public: + DECLARE_EXTENSION_FUNCTION("sockets.udp.setBroadcast", + SOCKETS_UDP_SETBROADCAST) + + SocketsUdpSetBroadcastFunction(); + + protected: + ~SocketsUdpSetBroadcastFunction() override; + + // AsyncApiFunction + bool Prepare() override; + void Work() override; + + private: + scoped_ptr<sockets_udp::SetBroadcast::Params> params_; +}; + } // namespace core_api } // namespace extensions diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index cdcdeb5..c182e48 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h @@ -1060,6 +1060,7 @@ enum HistogramValue { NETWORKINGPRIVATE_GETDEVICESTATES, DEVELOPERPRIVATE_GETPROFILECONFIGURATION, DEVELOPERPRIVATE_UPDATEPROFILECONFIGURATION, + SOCKETS_UDP_SETBROADCAST, // Last entry: Add new entries above and ensure to update // tools/metrics/histograms/histograms.xml. ENUM_BOUNDARY diff --git a/extensions/common/api/sockets_udp.idl b/extensions/common/api/sockets_udp.idl index 8ce5a23..784a31d 100644 --- a/extensions/common/api/sockets_udp.idl +++ b/extensions/common/api/sockets_udp.idl @@ -128,6 +128,10 @@ namespace sockets.udp { // |groups| : Array of groups the socket joined. callback GetJoinedGroupsCallback = void (DOMString[] groups); + // Callback from the <code>setBroadcast</code> method. + // |result| : The result code returned from the underlying network call. + callback SetBroadcastCallback = void (long result); + // Data from an <code>onReceive</code> event. dictionary ReceiveInfo { // The socket ID. @@ -291,6 +295,15 @@ namespace sockets.udp { // |callback| : Called with an array of strings of the result. static void getJoinedGroups(long socketId, GetJoinedGroupsCallback callback); + + // Enables or disables broadcast packets on this socket. + // + // |socketId| : The socket ID. + // |enabled| : <code>true</code> to enable broadcast packets, + // <code>false</code> to disable them. + static void setBroadcast(long socketId, + boolean enabled, + SetBroadcastCallback callback); }; interface Events { diff --git a/extensions/test/data/sockets_udp/api/background.js b/extensions/test/data/sockets_udp/api/background.js index 50dfff6..8382292 100644 --- a/extensions/test/data/sockets_udp/api/background.js +++ b/extensions/test/data/sockets_udp/api/background.js @@ -228,6 +228,94 @@ var testSetPaused = function() { } } +var testBroadcast = function() { + var listeningSocketId; + var sendingSocketId; + + console.log("testBroadcast"); + chrome.sockets.udp.create({}, onCreate); + + function onCreate(socketInfo) { + console.log("socket created: " + socketInfo.socketId); + chrome.test.assertTrue(socketId > 0, "failed to create socket"); + + if (listeningSocketId == undefined) { + listeningSocketId = socketInfo.socketId; + chrome.sockets.udp.onReceive.addListener(onReceive); + chrome.sockets.udp.onReceiveError.addListener(onReceiveError); + chrome.sockets.udp.bind( + listeningSocketId, "0.0.0.0", 8000, onBindListening); + } else { + sendingSocketId = socketInfo.socketId; + chrome.sockets.udp.bind( + sendingSocketId, "127.0.0.1", 8001, onBindSending); + } + } + + function onBindListening(result) { + chrome.test.assertEq(0, result, "Bind failed with error: " + result); + if (result < 0) { + return; + } + + chrome.sockets.udp.setBroadcast( + listeningSocketId, true, onSetBroadcastListening); + } + + function onSetBroadcastListening(result) { + chrome.test.assertEq(0, result, "Failed to enable broadcast: " + result); + if (result < 0) { + return; + } + + // Create the sending socket. + chrome.sockets.udp.create({}, onCreate); + } + + function onBindSending(result) { + chrome.test.assertEq(0, result, "Bind failed with error: " + result); + if (result < 0) { + return; + } + + chrome.sockets.udp.setBroadcast( + sendingSocketId, true, onSetBroadcastSending); + } + + function onSetBroadcastSending(result) { + chrome.test.assertEq(0, result, "Failed to enable broadcast: " + result); + if (result < 0) { + return; + } + + string2ArrayBuffer("broadcast packet", onArrayBuffer); + } + + function onArrayBuffer(arrayBuffer) { + console.log("sending bytes to broadcast: " + arrayBuffer.byteLength); + chrome.sockets.udp.send(sendingSocketId, arrayBuffer, "127.255.255.255", + 8000, function(sendInfo) { + chrome.test.assertEq(0, sendInfo.resultCode); + chrome.test.assertEq(sendInfo.bytesSent, arrayBuffer.byteLength); + }); + } + + function onReceiveError(info) { + chrome.test.fail("Socket receive error: " + info.resultCode); + } + + function onReceive(info) { + console.log("Received data on socket" + "(" + info.socketId + ")"); + chrome.test.assertEq(listeningSocketId, info.socketId); + chrome.test.assertEq("127.0.0.1", info.remoteAddress); + chrome.test.assertEq(8001, info.remotePort); + arrayBuffer2String(info.data, function(string) { + chrome.test.assertEq("broadcast packet", string); + chrome.test.succeed(); + }); + } +}; + /////////////////////////////////////////////////////////////////////////////// // Test driver // @@ -244,7 +332,8 @@ var onMessageReply = function(message) { chrome.test.runTests([ testMulticast ]); } else { console.log("Running udp tests"); - chrome.test.runTests([ testSocketCreation, testSending, testSetPaused ]); + chrome.test.runTests([ testSocketCreation, testSending, testSetPaused, + testBroadcast ]); } }; diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index 1f4e112..2d2ef79 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -50336,6 +50336,7 @@ Therefore, the affected-histogram name has to have at least one dot in it. <int value="999" label="NETWORKINGPRIVATE_GETDEVICESTATES"/> <int value="1000" label="DEVELOPERPRIVATE_GETPROFILECONFIGURATION"/> <int value="1001" label="DEVELOPERPRIVATE_UPDATEPROFILECONFIGURATION"/> + <int value="1002" label="SOCKETS_UDP_SETBROADCAST"/> </enum> <enum name="ExtensionInstallCause" type="int"> |