@ -1,15 +1,18 @@
# include <bitcoin/script.h>
# include <bitcoin/script.h>
# include <ccan/structeq/structeq.h>
# include <closingd/gen_closing_wire.h>
# include <closingd/gen_closing_wire.h>
# include <common/close_tx.h>
# include <common/close_tx.h>
# include <common/crypto_sync.h>
# include <common/crypto_sync.h>
# include <common/derive_basepoints.h>
# include <common/derive_basepoints.h>
# include <common/htlc.h>
# include <common/htlc.h>
# include <common/peer_failed.h>
# include <common/peer_failed.h>
# include <common/ping.h>
# include <common/status.h>
# include <common/status.h>
# include <common/subdaemon.h>
# include <common/subdaemon.h>
# include <common/type_to_string.h>
# include <common/type_to_string.h>
# include <common/utils.h>
# include <common/utils.h>
# include <common/version.h>
# include <common/version.h>
# include <common/wire_error.h>
# include <errno.h>
# include <errno.h>
# include <inttypes.h>
# include <inttypes.h>
# include <stdio.h>
# include <stdio.h>
@ -80,6 +83,92 @@ static u64 one_towards(u64 target, u64 value)
return value ;
return value ;
}
}
static void handle_ping ( const u8 * msg ,
struct crypto_state * cs ,
const struct channel_id * our_channel_id )
{
u8 * pong ;
if ( ! check_ping_make_pong ( msg , msg , & pong ) )
peer_failed ( PEER_FD , cs , our_channel_id , " Bad ping " ) ;
status_trace ( " Got ping, sending %s " , pong ?
wire_type_name ( fromwire_peektype ( pong ) )
: " nothing " ) ;
if ( pong & & ! sync_crypto_write ( cs , PEER_FD , take ( pong ) ) )
status_failed ( STATUS_FAIL_PEER_IO ,
" Failed writing pong: %s " , strerror ( errno ) ) ;
}
/* Handle random messages we might get, returning NULL if we handled it. */
static u8 * read_peer_msg ( const tal_t * ctx ,
struct crypto_state * cs ,
const struct channel_id * our_channel_id )
{
u8 * msg ;
struct channel_id channel_id ;
msg = sync_crypto_read ( ctx , cs , PEER_FD ) ;
if ( ! msg )
status_failed ( STATUS_FAIL_PEER_IO ,
" Failed reading from peer: %s " , strerror ( errno ) ) ;
if ( is_gossip_msg ( msg ) ) {
/* Forward to gossip daemon */
wire_sync_write ( GOSSIP_FD , take ( msg ) ) ;
return NULL ;
}
if ( fromwire_peektype ( msg ) = = WIRE_PING ) {
handle_ping ( msg , cs , our_channel_id ) ;
return tal_free ( msg ) ;
}
if ( fromwire_peektype ( msg ) = = WIRE_ERROR ) {
struct channel_id chanid ;
char * err = sanitize_error ( msg , msg , & chanid ) ;
/* BOLT #1:
*
* The channel is referred to by ` channel_id ` , unless
* ` channel_id ` is 0 ( i . e . all bytes are 0 ) , in which
* case it refers to all channels .
* . . .
* The receiving node :
* - upon receiving ` error ` :
* - MUST fail the channel referred to by the error
* message .
* - if no existing channel is referred to by the
* message :
* - MUST ignore the message .
*/
if ( channel_id_is_all ( & chanid )
| | structeq ( & chanid , our_channel_id ) ) {
status_failed ( STATUS_FAIL_PEER_BAD ,
" Received ERROR %s " , err ) ;
}
return tal_free ( msg ) ;
}
/* They're talking about a different channel? */
if ( extract_channel_id ( msg , & channel_id )
& & ! structeq ( & channel_id , our_channel_id ) ) {
status_trace ( " Rejecting %s for unknown channel_id %s " ,
wire_type_name ( fromwire_peektype ( msg ) ) ,
type_to_string ( msg , struct channel_id ,
& channel_id ) ) ;
sync_crypto_write ( cs , PEER_FD ,
take ( towire_errorfmt ( msg , & channel_id ,
" Multiple channels "
" unsupported " ) ) ) ;
return tal_free ( msg ) ;
}
return msg ;
}
static void do_reconnect ( struct crypto_state * cs ,
static void do_reconnect ( struct crypto_state * cs ,
const struct channel_id * channel_id ,
const struct channel_id * channel_id ,
const u64 next_index [ NUM_SIDES ] ,
const u64 next_index [ NUM_SIDES ] ,
@ -108,17 +197,8 @@ static void do_reconnect(struct crypto_state *cs,
status_failed ( STATUS_FAIL_PEER_IO ,
status_failed ( STATUS_FAIL_PEER_IO ,
" Failed writing reestablish: %s " , strerror ( errno ) ) ;
" Failed writing reestablish: %s " , strerror ( errno ) ) ;
again :
/* Wait for them to say something interesting */
msg = sync_crypto_read ( tmpctx , cs , PEER_FD ) ;
while ( ( msg = read_peer_msg ( tmpctx , cs , channel_id ) ) = = NULL ) ;
if ( ! msg )
status_failed ( STATUS_FAIL_PEER_IO ,
" Failed reading reestablish: %s " , strerror ( errno ) ) ;
if ( is_gossip_msg ( msg ) ) {
if ( ! wire_sync_write ( GOSSIP_FD , take ( msg ) ) )
status_failed ( STATUS_FAIL_GOSSIP_IO , " Writing gossip " ) ;
goto again ;
}
if ( ! fromwire_channel_reestablish ( msg , NULL , & their_channel_id ,
if ( ! fromwire_channel_reestablish ( msg , NULL , & their_channel_id ,
& next_local_commitment_number ,
& next_local_commitment_number ,
@ -263,17 +343,8 @@ int main(int argc, char *argv[])
break ;
break ;
again :
again :
msg = sync_crypto_read ( tmpctx , & cs , PEER_FD ) ;
/* Wait for them to say something interesting */
if ( ! msg )
while ( ( msg = read_peer_msg ( tmpctx , & cs , & channel_id ) ) = = NULL ) ;
status_failed ( STATUS_FAIL_PEER_IO , " Reading input " ) ;
/* We don't send gossip at this stage, but we can recv it */
if ( is_gossip_msg ( msg ) ) {
if ( ! wire_sync_write ( GOSSIP_FD , take ( msg ) ) )
status_failed ( STATUS_FAIL_GOSSIP_IO ,
" Writing gossip " ) ;
goto again ;
}
/* BOLT #2:
/* BOLT #2:
*
*