@@ -9,6 +9,26 @@ const debug = Debug('ionic:cli-framework:utils:network');
9
9
10
10
export const ERROR_NETWORK_ADDRESS_NOT_AVAIL = 'NETWORK_ADDRESS_NOT_AVAIL' ;
11
11
12
+ export const DEFAULT_ADDRESSES : ReadonlyArray < string > = getDefaultAddresses ( ) ;
13
+
14
+ function getDefaultAddresses ( ) : string [ ] {
15
+ const addresses : string [ ] = [ '0.0.0.0' ] ;
16
+
17
+ try {
18
+ const networkInterfaces = os . networkInterfaces ( ) ;
19
+
20
+ for ( const device of Object . keys ( networkInterfaces ) ) {
21
+ const networkInterface = networkInterfaces [ device ] ;
22
+
23
+ addresses . push ( ...networkInterface . map ( i => i . address ) ) ;
24
+ }
25
+ } catch ( e ) {
26
+ // swallow
27
+ }
28
+
29
+ return addresses ;
30
+ }
31
+
12
32
export function getExternalIPv4Interfaces ( ) : NetworkInterface [ ] {
13
33
const networkInterfaces = os . networkInterfaces ( ) ;
14
34
const devices : NetworkInterface [ ] = [ ] ;
@@ -26,9 +46,17 @@ export function getExternalIPv4Interfaces(): NetworkInterface[] {
26
46
return devices ;
27
47
}
28
48
29
- export async function findClosestOpenPort ( port : number , host ?: string ) : Promise < number > {
49
+ /**
50
+ * Attempts to locate a port number starting from `port` and incrementing by 1.
51
+ *
52
+ * This function looks through all internal network interfaces, attempting
53
+ * host/port combinations until it finds an available port on all interfaces.
54
+ *
55
+ * @param port The port at which to start checking.
56
+ */
57
+ export async function findClosestOpenPort ( port : number ) : Promise < number > {
30
58
async function t ( portToCheck : number ) : Promise < number > {
31
- if ( await isPortAvailable ( portToCheck , host ) ) {
59
+ if ( await isPortAvailable ( portToCheck ) ) {
32
60
return portToCheck ;
33
61
}
34
62
@@ -38,7 +66,33 @@ export async function findClosestOpenPort(port: number, host?: string): Promise<
38
66
return t ( port ) ;
39
67
}
40
68
41
- export async function isPortAvailable ( port : number , host ?: string ) : Promise < boolean > {
69
+ /**
70
+ * Checks whether a port is open or closed.
71
+ *
72
+ * This function looks through all internal network interfaces, checking
73
+ * whether all host/port combinations are open. If one or more is not, the port
74
+ * is not available.
75
+ */
76
+ export async function isPortAvailable ( port : number ) : Promise < boolean > {
77
+ let available = true ;
78
+
79
+ for ( const address of DEFAULT_ADDRESSES ) {
80
+ try {
81
+ debug ( 'checking for open port on %s:%d' , address , port ) ;
82
+ available = await isPortAvailableForHost ( address , port ) ;
83
+
84
+ if ( ! available ) {
85
+ return false ;
86
+ }
87
+ } catch ( e ) {
88
+ debug ( 'error while checking %s:%d: %o' , address , port , e ) ;
89
+ }
90
+ }
91
+
92
+ return available ;
93
+ }
94
+
95
+ export function isPortAvailableForHost ( host : string , port : number ) : Promise < boolean > {
42
96
return new Promise < boolean > ( ( resolve , reject ) => {
43
97
const tester = net . createServer ( )
44
98
. once ( 'error' , ( err : any ) => {
0 commit comments