@@ -313,6 +313,77 @@ struct io_plan *peer_connected(struct io_conn *conn,
313313 return multiplex_peer_setup (conn , peer );
314314}
315315
316+ static bool verify_alt_addr (struct io_conn * conn ,
317+ struct daemon * daemon ,
318+ const struct node_id * id )
319+ {
320+ struct sockaddr_in local_addr ;
321+ socklen_t addr_len = sizeof (local_addr );
322+
323+ /* Get local address and port */
324+ if (getsockname (io_conn_fd (conn ), (struct sockaddr * )& local_addr ,
325+ & addr_len ) == -1 ) {
326+ status_broken ("verify_alt_addr: getsockname failed" );
327+ return false;
328+ }
329+
330+ char listening_addr [INET_ADDRSTRLEN ];
331+ if (!inet_ntop (AF_INET , & local_addr .sin_addr , listening_addr ,
332+ sizeof (listening_addr ))) {
333+ status_broken ("verify_alt_addr: inet_ntop failed" );
334+ return false;
335+ }
336+ int listening_port = ntohs (local_addr .sin_port );
337+
338+ char full_listening_addr [INET_ADDRSTRLEN + 6 ];
339+ snprintf (full_listening_addr , sizeof (full_listening_addr ), "%s:%d" ,
340+ listening_addr , listening_port );
341+
342+ struct wireaddr_internal search_addr ;
343+ if (parse_wireaddr_internal (tmpctx , full_listening_addr , 0 ,
344+ false, & search_addr ) != NULL ) {
345+ status_broken ("verify_alt_addr: parse_wireaddr_internal failed" );
346+ return false;
347+ }
348+
349+ struct whitelisted_peer * wp = whitelisted_peer_htable_get (daemon -> whitelisted_peer_htable ,
350+ id );
351+ bool is_whitelisted = false;
352+
353+ if (wp ) {
354+ size_t num_addrs = tal_count (wp -> my_alt_addrs );
355+ for (size_t i = 0 ; i < num_addrs ; ++ i ) {
356+ char * whitelist_addr_str = fmt_wireaddr_internal (tmpctx ,
357+ & wp -> my_alt_addrs [i ]);
358+ if (strcmp (full_listening_addr , whitelist_addr_str ) == 0 ) {
359+ is_whitelisted = true;
360+ status_debug ("Peer's address %s is in the whitelist. Accepting connection." ,
361+ full_listening_addr );
362+ goto check_alt_bind_addr ;
363+ }
364+ }
365+ }
366+
367+ check_alt_bind_addr :
368+ /* Check against alt_bind_addr only if the connection is not whitelisted */
369+ if (!is_whitelisted ) {
370+ char * alt_bind_addrs = tal_strdup (tmpctx ,
371+ (const char * )daemon -> alt_bind_addr );
372+ for (char * alt_bind_token = strtok (alt_bind_addrs , "," );
373+ alt_bind_token ;
374+ alt_bind_token = strtok (NULL , "," )) {
375+ if (strcmp (full_listening_addr , alt_bind_token ) == 0 ) {
376+ status_unusual ("Connection attempt from address %s which is not in the whitelist. Closing connection." ,
377+ full_listening_addr );
378+ tal_free (alt_bind_addrs );
379+ return false;
380+ }
381+ }
382+ tal_free (alt_bind_addrs );
383+ }
384+ return true;
385+ }
386+
316387/*~ handshake.c's handles setting up the crypto state once we get a connection
317388 * in; we hand it straight to peer_exchange_initmsg() to send and receive INIT
318389 * and call peer_connected(). */
@@ -327,6 +398,12 @@ static struct io_plan *handshake_in_success(struct io_conn *conn,
327398 struct node_id id ;
328399 node_id_from_pubkey (& id , id_key );
329400 status_peer_debug (& id , "Connect IN" );
401+
402+ /* Confirm that peer connects to the alt-bind-addr you sent */
403+ if (daemon -> alt_bind_addr )
404+ if (!verify_alt_addr (conn , daemon , & id ))
405+ return (io_close (conn ));
406+
330407 return peer_exchange_initmsg (conn , daemon , daemon -> our_features ,
331408 cs , & id , addr , timeout , is_websocket , true);
332409}
@@ -1438,7 +1515,8 @@ static void connect_init(struct daemon *daemon, const u8 *msg)
14381515 & dev_disconnect ,
14391516 & daemon -> dev_no_ping_timer ,
14401517 & daemon -> dev_handshake_no_reply ,
1441- & dev_throttle_gossip )) {
1518+ & dev_throttle_gossip ,
1519+ & daemon -> alt_bind_addr )) {
14421520 /* This is a helper which prints the type expected and the actual
14431521 * message, then exits (it should never be called!). */
14441522 master_badmsg (WIRE_CONNECTD_INIT , msg );
@@ -1925,6 +2003,7 @@ static void dev_connect_memleak(struct daemon *daemon, const u8 *msg)
19252003 memleak_scan_obj (memtable , daemon );
19262004 memleak_scan_htable (memtable , & daemon -> peers -> raw );
19272005 memleak_scan_htable (memtable , & daemon -> scid_htable -> raw );
2006+ memleak_scan_htable (memtable , & daemon -> whitelisted_peer_htable -> raw );
19282007
19292008 found_leak = dump_memleak (memtable , memleak_status_broken , NULL );
19302009 daemon_conn_send (daemon -> master ,
@@ -2161,6 +2240,18 @@ static void dev_exhaust_fds(struct daemon *daemon, const u8 *msg)
21612240 daemon -> dev_exhausted_fds = true;
21622241}
21632242
2243+ static void handle_alt_addr_whitelist (struct daemon * daemon , const u8 * msg )
2244+ {
2245+ struct whitelisted_peer * received_peers ;
2246+
2247+ if (!fromwire_connectd_alt_addr_whitelist (daemon , msg , & received_peers )) {
2248+ master_badmsg (WIRE_CONNECTD_ALT_ADDR_WHITELIST , msg );
2249+ return ;
2250+ }
2251+
2252+ populate_whitelist_table (daemon , received_peers );
2253+ }
2254+
21642255static struct io_plan * recv_peer_connect_subd (struct io_conn * conn ,
21652256 const u8 * msg ,
21662257 int fd ,
@@ -2262,6 +2353,10 @@ static struct io_plan *recv_req(struct io_conn *conn,
22622353 goto out ;
22632354 }
22642355 /* Fall thru */
2356+ case WIRE_CONNECTD_ALT_ADDR_WHITELIST :
2357+ handle_alt_addr_whitelist (daemon , msg );
2358+ goto out ;
2359+ /* Fall thru */
22652360 /* We send these, we don't receive them */
22662361 case WIRE_CONNECTD_INIT_REPLY :
22672362 case WIRE_CONNECTD_ACTIVATE_REPLY :
@@ -2363,6 +2458,9 @@ int main(int argc, char *argv[])
23632458 daemon -> gossip_stream_limit = 1000000 ;
23642459 daemon -> scid_htable = tal (daemon , struct scid_htable );
23652460 scid_htable_init (daemon -> scid_htable );
2461+ daemon -> whitelisted_peer_htable = tal (daemon ,
2462+ struct whitelisted_peer_htable );
2463+ whitelisted_peer_htable_init (daemon -> whitelisted_peer_htable );
23662464
23672465 /* stdin == control */
23682466 daemon -> master = daemon_conn_new (daemon , STDIN_FILENO , recv_req , NULL ,
0 commit comments