summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreillyg <reillyg@chromium.org>2015-04-10 20:47:21 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-11 03:48:05 +0000
commit92c5e06599547fa733d45f4c000a31acbe0c66f8 (patch)
tree65d1d37266e4a561c982176db39921fbbd05b7bb
parent9045adae17d792e3d0c475f90e906de2b29df1e2 (diff)
downloadchromium_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.cc7
-rw-r--r--extensions/browser/api/socket/udp_socket.h2
-rw-r--r--extensions/browser/api/sockets_udp/sockets_udp_api.cc26
-rw-r--r--extensions/browser/api/sockets_udp/sockets_udp_api.h18
-rw-r--r--extensions/browser/extension_function_histogram_value.h1
-rw-r--r--extensions/common/api/sockets_udp.idl13
-rw-r--r--extensions/test/data/sockets_udp/api/background.js91
-rw-r--r--tools/metrics/histograms/histograms.xml1
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">