1// Flags: --expose-internals
2'use strict';
3
4const common = require('../common');
5const {
6  ok,
7  strictEqual,
8  throws,
9} = require('assert');
10const {
11  SocketAddress,
12} = require('net');
13
14const {
15  InternalSocketAddress,
16} = require('internal/socketaddress');
17const { internalBinding } = require('internal/test/binding');
18const {
19  SocketAddress: _SocketAddress,
20  AF_INET
21} = internalBinding('block_list');
22
23{
24  const sa = new SocketAddress();
25  strictEqual(sa.address, '127.0.0.1');
26  strictEqual(sa.port, 0);
27  strictEqual(sa.family, 'ipv4');
28  strictEqual(sa.flowlabel, 0);
29
30  const mc = new MessageChannel();
31  mc.port1.onmessage = common.mustCall(({ data }) => {
32    ok(SocketAddress.isSocketAddress(data));
33
34    strictEqual(data.address, '127.0.0.1');
35    strictEqual(data.port, 0);
36    strictEqual(data.family, 'ipv4');
37    strictEqual(data.flowlabel, 0);
38
39    mc.port1.close();
40  });
41  mc.port2.postMessage(sa);
42}
43
44{
45  const sa = new SocketAddress({});
46  strictEqual(sa.address, '127.0.0.1');
47  strictEqual(sa.port, 0);
48  strictEqual(sa.family, 'ipv4');
49  strictEqual(sa.flowlabel, 0);
50}
51
52{
53  const sa = new SocketAddress({
54    address: '123.123.123.123',
55  });
56  strictEqual(sa.address, '123.123.123.123');
57  strictEqual(sa.port, 0);
58  strictEqual(sa.family, 'ipv4');
59  strictEqual(sa.flowlabel, 0);
60}
61
62{
63  const sa = new SocketAddress({
64    address: '123.123.123.123',
65    port: 80
66  });
67  strictEqual(sa.address, '123.123.123.123');
68  strictEqual(sa.port, 80);
69  strictEqual(sa.family, 'ipv4');
70  strictEqual(sa.flowlabel, 0);
71}
72
73{
74  const sa = new SocketAddress({
75    family: 'ipv6'
76  });
77  strictEqual(sa.address, '::');
78  strictEqual(sa.port, 0);
79  strictEqual(sa.family, 'ipv6');
80  strictEqual(sa.flowlabel, 0);
81}
82
83{
84  const sa = new SocketAddress({
85    family: 'ipv6',
86    flowlabel: 1,
87  });
88  strictEqual(sa.address, '::');
89  strictEqual(sa.port, 0);
90  strictEqual(sa.family, 'ipv6');
91  strictEqual(sa.flowlabel, 1);
92}
93
94[1, false, 'hello'].forEach((i) => {
95  throws(() => new SocketAddress(i), {
96    code: 'ERR_INVALID_ARG_TYPE'
97  });
98});
99
100[1, false, {}, [], 'test'].forEach((family) => {
101  throws(() => new SocketAddress({ family }), {
102    code: 'ERR_INVALID_ARG_VALUE'
103  });
104});
105
106[1, false, {}, []].forEach((address) => {
107  throws(() => new SocketAddress({ address }), {
108    code: 'ERR_INVALID_ARG_TYPE'
109  });
110});
111
112[-1, false, {}, []].forEach((port) => {
113  throws(() => new SocketAddress({ port }), {
114    code: 'ERR_SOCKET_BAD_PORT'
115  });
116});
117
118throws(() => new SocketAddress({ flowlabel: -1 }), {
119  code: 'ERR_OUT_OF_RANGE'
120});
121
122{
123  // Test that the internal helper class InternalSocketAddress correctly
124  // inherits from SocketAddress and that it does not throw when its properties
125  // are accessed.
126
127  const address = '127.0.0.1';
128  const port = 8080;
129  const flowlabel = 0;
130  const handle = new _SocketAddress(address, port, AF_INET, flowlabel);
131  const addr = new InternalSocketAddress(handle);
132  ok(addr instanceof SocketAddress);
133  strictEqual(addr.address, address);
134  strictEqual(addr.port, port);
135  strictEqual(addr.family, 'ipv4');
136  strictEqual(addr.flowlabel, flowlabel);
137}
138