1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23const common = require('../common'); 24const assert = require('assert'); 25const net = require('net'); 26 27let tests_run = 0; 28 29function pingPongTest(host, on_complete) { 30 const N = 1000; 31 let count = 0; 32 let sent_final_ping = false; 33 34 const server = net.createServer({ allowHalfOpen: true }, function(socket) { 35 assert.strictEqual(socket.remoteAddress !== null, true); 36 assert.strictEqual(socket.remoteAddress !== undefined, true); 37 const address = socket.remoteAddress; 38 if (host === '127.0.0.1') { 39 assert.strictEqual(address, '127.0.0.1'); 40 } else if (host == null || host === 'localhost') { 41 assert(address === '127.0.0.1' || address === '::ffff:127.0.0.1'); 42 } else { 43 console.log(`host = ${host}, remoteAddress = ${address}`); 44 assert.strictEqual(address, '::1'); 45 } 46 47 socket.setEncoding('utf8'); 48 socket.setNoDelay(); 49 socket.timeout = 0; 50 51 socket.on('data', function(data) { 52 console.log(`server got: ${JSON.stringify(data)}`); 53 assert.strictEqual(socket.readyState, 'open'); 54 assert.strictEqual(count <= N, true); 55 if (/PING/.test(data)) { 56 socket.write('PONG'); 57 } 58 }); 59 60 socket.on('end', function() { 61 assert.strictEqual(socket.readyState, 'writeOnly'); 62 socket.end(); 63 }); 64 65 socket.on('close', function(had_error) { 66 assert.strictEqual(had_error, false); 67 assert.strictEqual(socket.readyState, 'closed'); 68 socket.server.close(); 69 }); 70 }); 71 72 server.listen(0, host, function() { 73 const client = net.createConnection(server.address().port, host); 74 75 client.setEncoding('utf8'); 76 77 client.on('connect', function() { 78 assert.strictEqual(client.readyState, 'open'); 79 client.write('PING'); 80 }); 81 82 client.on('data', function(data) { 83 console.log(`client got: ${data}`); 84 85 assert.strictEqual(data, 'PONG'); 86 count += 1; 87 88 if (sent_final_ping) { 89 assert.strictEqual(client.readyState, 'readOnly'); 90 return; 91 } 92 assert.strictEqual(client.readyState, 'open'); 93 94 if (count < N) { 95 client.write('PING'); 96 } else { 97 sent_final_ping = true; 98 client.write('PING'); 99 client.end(); 100 } 101 }); 102 103 client.on('close', function() { 104 assert.strictEqual(count, N + 1); 105 assert.strictEqual(sent_final_ping, true); 106 if (on_complete) on_complete(); 107 tests_run += 1; 108 }); 109 }); 110} 111 112// All are run at once and will run on different ports. 113pingPongTest('localhost'); 114pingPongTest(null); 115 116if (common.hasIPv6) pingPongTest('::1'); 117 118process.on('exit', function() { 119 assert.strictEqual(tests_run, common.hasIPv6 ? 3 : 2); 120}); 121