summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreillyg <reillyg@chromium.org>2015-11-23 13:41:47 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-23 21:42:44 +0000
commit97b9851546675bd7ccc4d1dfb48cddbf3502ca94 (patch)
tree534b899a7caa972e5f314857b7835b7d2a99db6b
parentfd9f7970b7e7f650fa7b07dbdf308ce28f744ffd (diff)
downloadchromium_src-97b9851546675bd7ccc4d1dfb48cddbf3502ca94.zip
chromium_src-97b9851546675bd7ccc4d1dfb48cddbf3502ca94.tar.gz
chromium_src-97b9851546675bd7ccc4d1dfb48cddbf3502ca94.tar.bz2
Reset server_socket_ when listen fails in extensions::TCPSocket.
net::TCPServerSocket::Listen will close its internal socket if it fails to bind and begin listening. This leaves the extensions socket object in a bad state. Instead reset the socket so that an application can try to bind it again. BUG=559368 Review URL: https://codereview.chromium.org/1463293004 Cr-Commit-Position: refs/heads/master@{#361191}
-rw-r--r--chrome/test/data/extensions/api_test/socket/api/background.js46
-rw-r--r--extensions/browser/api/socket/tcp_socket.cc4
2 files changed, 48 insertions, 2 deletions
diff --git a/chrome/test/data/extensions/api_test/socket/api/background.js b/chrome/test/data/extensions/api_test/socket/api/background.js
index 35ecffa..ff4864a 100644
--- a/chrome/test/data/extensions/api_test/socket/api/background.js
+++ b/chrome/test/data/extensions/api_test/socket/api/background.js
@@ -206,6 +206,7 @@ var testSocketListening = function() {
setTimeout(function() {
socket.getInfo(acceptedSocketId, function(info) {
chrome.test.assertFalse(info.connected);
+ socket.destroy(socketId);
chrome.test.succeed();
});
}, 500);
@@ -247,6 +248,46 @@ var testSocketListening = function() {
socket.create('tcp', {}, onServerSocketCreate);
};
+// Tests creation of a TCP listening socket on a port that is already in use.
+var testSocketListenInUse = function() {
+ var tmpSocketId;
+
+ function onAccept(result) {
+ chrome.test.assertNoLastError();
+ chrome.test.assertEq(-2, result.resultCode);
+ socket.destroy(socketId);
+ socket.destroy(tmpSocketId);
+ chrome.test.succeed();
+ }
+
+ function onSecondSocketListen(result) {
+ chrome.test.assertLastError("Could not listen on the specified port.");
+ chrome.test.assertEq(-147, result);
+ // Calling accept on this socket should fail since it isn't listening.
+ socket.accept(tmpSocketId, onAccept);
+ }
+
+ function onSecondSocketCreate(socketInfo) {
+ chrome.test.assertNoLastError();
+ tmpSocketId = socketInfo.socketId;
+ socket.listen(tmpSocketId, address, port, onSecondSocketListen);
+ }
+
+ function onFirstSocketListen(result) {
+ chrome.test.assertNoLastError();
+ chrome.test.assertEq(0, result);
+ socket.create('tcp', {}, onSecondSocketCreate);
+ }
+
+ function onFirstSocketCreate(socketInfo) {
+ chrome.test.assertNoLastError();
+ socketId = socketInfo.socketId;
+ socket.listen(socketId, address, port, onFirstSocketListen);
+ }
+
+ socket.create('tcp', {}, onFirstSocketCreate);
+};
+
var testPendingCallback = function() {
dataRead = "";
succeeded = false;
@@ -374,7 +415,10 @@ var onMessageReply = function(message) {
console.log("Running tests, protocol " + protocol + ", echo server " +
address + ":" + port);
if (test_type == 'tcp_server') {
- chrome.test.runTests([ testSocketListening ]);
+ chrome.test.runTests([
+ testSocketListening,
+ testSocketListenInUse
+ ]);
} else if (test_type == 'multicast') {
console.log("Running multicast tests");
chrome.test.runTests([ testMulticast ]);
diff --git a/extensions/browser/api/socket/tcp_socket.cc b/extensions/browser/api/socket/tcp_socket.cc
index 8d5257b..79558d4 100644
--- a/extensions/browser/api/socket/tcp_socket.cc
+++ b/extensions/browser/api/socket/tcp_socket.cc
@@ -196,8 +196,10 @@ int TCPSocket::Listen(const std::string& address,
}
int result = server_socket_->ListenWithAddressAndPort(address, port, backlog);
- if (result)
+ if (result) {
+ server_socket_.reset();
*error_msg = kSocketListenError;
+ }
return result;
}