listen/bind errors should close net.Server
authorRyan Dahl <ry@tinyclouds.org>
Wed, 19 Jan 2011 00:22:43 +0000 (16:22 -0800)
committerRyan Dahl <ry@tinyclouds.org>
Wed, 19 Jan 2011 00:22:43 +0000 (16:22 -0800)
lib/net.js
test/simple/test-net-server-try-ports.js [new file with mode: 0644]

index efaf816..c057eeb 100644 (file)
@@ -1020,6 +1020,7 @@ Server.prototype._doListen = function() {
   try {
     bind(self.fd, arguments[0], arguments[1]);
   } catch (err) {
+    self.close();
     self.emit('error', err);
     return;
   }
@@ -1035,6 +1036,7 @@ Server.prototype._doListen = function() {
     try {
       listen(self.fd, self._backlog || 128);
     } catch (err) {
+      self.close();
       self.emit('error', err);
       return;
     }
diff --git a/test/simple/test-net-server-try-ports.js b/test/simple/test-net-server-try-ports.js
new file mode 100644 (file)
index 0000000..91b8982
--- /dev/null
@@ -0,0 +1,55 @@
+// This tests binds to one port, then attempts to start a server on that
+// port. It should be EADDRINUSE but be able to then bind to another port.
+var common = require('../common');
+var assert = require('assert');
+var net = require('net');
+
+var connections = 0;
+
+var server1listening = false;
+var server2listening = false;
+
+var server1 = net.Server(function (socket) {
+  connections++;
+  socket.destroy();
+});
+
+var server2 = net.Server(function (socket) {
+  connections++;
+  socket.destroy();
+});
+
+var server2errors = 0;
+server2.on('error', function() {
+  server2errors++;
+  console.error("server2 error");
+});
+
+
+server1.listen(common.PORT, function () {
+  console.error("server1 listening");
+  server1listening = true;
+  // This should make server2 emit EADDRINUSE
+  server2.listen(common.PORT);
+
+  // Wait a bit, now try again.
+  // TODO, the listen callback should report if there was an error.
+  // Then we could avoid this very unlikely but potential race condition
+  // here.
+  setTimeout(function() {
+    server2.listen(common.PORT + 1, function () {
+      console.error("server2 listening");
+      server2listening = true;
+
+      server1.close();
+      server2.close();
+    });
+  }, 100);
+});
+
+
+process.on('exit', function() {
+  assert.equal(1, server2errors);
+  assert.ok(server2listening);
+  assert.ok(server1listening);
+});