@@ -39,20 +39,29 @@ class BonjourClient extends events.EventEmitter implements dnssd.Client {
3939 // interface (actually, each address of each interface, which could be
4040 // more than one).
4141 private updateInterfaces ( ) {
42- const newAddresses = new Array < string > ( ) ;
42+ type Address = { iface : number , address : string } ;
43+ const newAddresses = new Array < Address > ( ) ;
4344 const ifaces = os . networkInterfaces ( ) ;
4445 for ( let i in ifaces ) {
46+ // on Windows, only the local link address has a scopeid that matches
47+ // the index of the network interface.
48+ const localLinkAddr = ifaces [ i ] . find ( v => v . address . startsWith ( 'fe80:' ) ) ;
49+ if ( ! localLinkAddr ) {
50+ continue ;
51+ }
52+ const ifaceIndex = ( < os . NetworkInterfaceInfoIPv6 > localLinkAddr ) . scopeid ;
53+
4554 // only supporting IPv6 for now
46- const addresses = ifaces [ i ] . filter ( v => v . family === 'IPv6' ) . map ( v =>
55+ const addresses = ifaces [ i ] . filter ( v => v . internal === false && v . family === 'IPv6' ) . map ( v =>
4756 `${ v . address } %${ process . platform === 'win32' ? ( < os . NetworkInterfaceInfoIPv6 > v ) . scopeid : i } ` ) ;
48- newAddresses . push ( ...addresses ) ;
57+ newAddresses . push ( ...addresses . map ( v => < Address > { iface : ifaceIndex , address : v } ) ) ;
4958 }
50- const added = newAddresses . filter ( a => this . ifaceAddresses . indexOf ( a ) === - 1 ) ;
51- const removed = this . ifaceAddresses . filter ( a => newAddresses . indexOf ( a ) === - 1 ) ;
59+ const added = newAddresses . filter ( a => this . ifaceAddresses . indexOf ( a . address ) === - 1 ) ;
60+ const removed = this . ifaceAddresses . filter ( a => newAddresses . findIndex ( v => v . address === a ) === - 1 ) ;
5261 if ( added . length ) {
5362 for ( const a of added ) {
54- this . ifaceAddresses . push ( a ) ;
55- this . createClient ( a ) ;
63+ this . ifaceAddresses . push ( a . address ) ;
64+ this . createClient ( a . iface , a . address ) ;
5665 }
5766 }
5867 if ( removed . length ) {
@@ -66,17 +75,18 @@ class BonjourClient extends events.EventEmitter implements dnssd.Client {
6675
6776 /**
6877 * Asyncronusly create an new bonjour.Bonjour client object
78+ * @param ifaceIndex the index of the network interface
6979 * @param ifaceAddress the IP address
7080 */
71- private createClient ( ifaceAddress : string ) : void {
81+ private createClient ( ifaceIndex : number , ifaceAddress : string ) : void {
7282 // work around bonjour issue where error is not handled
7383 new Promise < bonjour . Bonjour > ( ( resolve , reject ) => {
7484 const bClient = bonjour ( < any > {
7585 type : 'udp6' ,
7686 ip : 'ff02::fb' ,
7787 interface : ifaceAddress
7888 } ) ;
79- ( < any > bClient ) [ 'iface' ] = ifaceAddress . split ( '%' ) [ 1 ] ;
89+ ( < any > bClient ) [ 'iface' ] = ifaceIndex ;
8090 ( < any > bClient ) . _server . mdns . on ( 'ready' , ( ) => resolve ( bClient ) ) ;
8191 ( < any > bClient ) . _server . mdns . on ( 'error' , ( err : any ) => reject ( err ) ) ;
8292 } ) . then ( bClient => {
@@ -94,7 +104,7 @@ class BonjourClient extends events.EventEmitter implements dnssd.Client {
94104 // we are bound or the interface goes away.
95105 setTimeout ( ( ) => {
96106 if ( this . ifaceAddresses . indexOf ( ifaceAddress ) >= 0 ) {
97- this . createClient ( ifaceAddress ) ;
107+ this . createClient ( ifaceIndex , ifaceAddress ) ;
98108 }
99109 } , 500 ) ;
100110 }
@@ -143,6 +153,15 @@ class BonjourBrowser extends events.EventEmitter implements dnssd.Browser {
143153 const services = new Array < BonjourService > ( ) ;
144154 browser . on ( 'up' , s => {
145155 ( < any > s ) [ 'iface' ] = ( < any > bClient ) [ 'iface' ] ;
156+ for ( const b of this . browsers ) {
157+ for ( const bs of b . services ) {
158+ const bss = bs . bService ;
159+ if ( ( < any > s ) [ 'iface' ] === ( < any > bss ) [ 'iface' ] && s . name === bs . name && s . type === bss . type && s . fqdn === bss . fqdn . replace ( / \. $ / , '' ) ) {
160+ // ignore duplicates
161+ return ;
162+ }
163+ }
164+ }
146165 const service = new BonjourService ( s ) ;
147166 services . push ( service ) ;
148167 this . emit ( 'added' , service , false ) ;
0 commit comments