Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -217,7 +217,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
// Disconnect all peers
for (idx, peer) in self.peers.borrow().iter().enumerate() {
if *peer {
self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers});
self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers});
}
}

Expand DownExpand Up@@ -378,7 +378,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
2 => {
let peer_id = get_slice!(1)[0];
if !peers.borrow()[peer_id as usize] { return; }
loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers});
peers.borrow_mut()[peer_id as usize] = false;
},
3 => {
Expand Down
4 changes: 2 additions & 2 deletions lightning-net-tokio/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ impl Connection {
return future::Either::A(blocker.then(|_| { Ok(()) }));
}
}
//TODO: There's a race where we don't meet the requirements of disconnect_socket if its
//TODO: There's a race where we don't meet the requirements of socket_disconnected if its
//called right here, after we release the us_ref lock in the scope above, but before we
//call read_event!
match peer_manager.read_event(&mut SocketDescriptor::new(us_ref.clone(), peer_manager.clone()), pending_read) {
Expand All@@ -84,7 +84,7 @@ impl Connection {
future::Either::B(future::result(Ok(())))
}).then(move |_| {
if us_close_ref.lock().unwrap().need_disconnect {
peer_manager_ref.disconnect_event(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
peer_manager_ref.socket_disconnected(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
println!("Peer disconnected!");
} else {
println!("We disconnected peer!");
Expand Down
60 changes: 35 additions & 25 deletions lightning/src/ln/peer_handler.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,12 +49,12 @@ pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandl
/// You probably want to just extend an int and put a file descriptor in a struct and implement
/// send_data. Note that if you are using a higher-level net library that may close() itself, be
/// careful to ensure you don't have races whereby you might register a new connection with an fd
/// the same as a yet-to-be-disconnect_event()-ed.
/// the same as a yet-to-be-socket_disconnected()-ed.
Comment on lines 51 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the emphasized is saying:

whereby you might register a new connection with an fd the same as a yet-to-be-socket_disconnected()-ed.

Something seems grammatically off or perhaps I'm just not parsing this correctly.

pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// Attempts to send some data from the given slice to the peer.
///
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
/// Note that in the disconnected case, a disconnect_event must still fire and further write
/// Note that in the disconnected case, a socket_disconnected must still fire and further write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "a".

/// attempts may occur until that time.
///
/// If the returned size is smaller than data.len(), a write_available event must
Expand All@@ -67,17 +67,18 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// *not* imply that further read events should be paused.
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize;
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
/// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
/// No disconnect_event should be generated as a result of this call, though obviously races
/// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
/// that event completing.
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
/// though obviously races may occur whereby disconnect_socket is called after a call to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "obviously". The reason for including the comment is that this behavior is not obvious.

/// socket_disconnected but prior to that event completing.
Comment on lines -70 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"No disconnect_event" was changed to "No socket_disconnected call" here but later in the comment "event" is still used.

prior to that event completing

Rather than replacing "event" with "call", I'd recommend re-wording to something a little less ambiguous such as:

prior to the former completing

fn disconnect_socket(&mut self);
}

/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
/// generate no further read/write_events for the descriptor, only triggering a single
/// disconnect_event (unless it was provided in response to a new_*_connection event, in which case
/// no such disconnect_event must be generated and the socket be silently disconencted).
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
/// triggering a single socket_disconnected call (unless it was provided in response to a
/// new_*_connection event, in which case no such socket_disconnected() must be generated and the
/// socket be silently disconencted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar: must be

pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
Expand DownExpand Up@@ -201,7 +202,7 @@ macro_rules! encode_msg {
}

/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after disconnect_event() has been called.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where CM::Target: msgs::ChannelMessageHandler {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
Expand DownExpand Up@@ -254,13 +255,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
}

/// Indicates a new outbound connection has been established to a node with the given node_id.
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// Returns a small number of bytes to send to the remote node (currently always 50).
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
/// socket_disconnected().
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
Expand DownExpand Up@@ -294,11 +295,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// call disconnect_event for the new descriptor but must disconnect the connection
/// call socket_disconnected for the new descriptor but must disconnect the connection
/// immediately.
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
/// socket_disconnected called.
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
Expand DownExpand Up@@ -406,10 +407,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
/// new_*\_connection) before returning. Thus, be very careful with reentrancy issues! The
/// invariants around calling write_event in case a write did not fully complete must still
/// hold - be ready to call write_event again if a write call generated here isn't sufficient!
/// Panics if the descriptor was not previously registered in a new_\*_connection event.
pub fn write_event(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
/// new_\*_connection event.
pub fn write_buffer_space_avail(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
let mut peers = self.peers.lock().unwrap();
match peers.peers.get_mut(descriptor) {
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Expand All@@ -429,8 +431,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
/// Thus, however, you almost certainly want to call process_events() after any read_event to
/// generate send_data calls to handle responses.
///
/// If Ok(true) is returned, further read_events should not be triggered until a write_event on
/// this file descriptor has resume_read set (preventing DoS issues in the send buffer).
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
///
/// Panics if the descriptor was not previously registered in a new_*_connection event.
pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec<u8>) -> Result<bool, PeerHandleError> {
Expand DownExpand Up@@ -1036,11 +1038,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where

/// Indicates that the given socket descriptor's connection is now closed.
///
/// This must be called even if a PeerHandleError was given for a read_event or write_event,
/// but must NOT be called if a PeerHandleError was provided out of a new_\*\_connection event!
/// This must only be called if the socket has been disconnected by the peer or your own
/// decision to disconnect it and must NOT be called in any case where other parts of this
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the user supposed to differentiate between their own call to disconnect_socket and that of this library?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, disconnect_socket is different from socket_disconnected - I suppose a user could call disconnect_socket on their own Descriptor, but in general I presumed they wouldn't (and would just call shutdown(2)).

/// the peer.
///
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
pub fn disconnect_event(&self, descriptor: &Descriptor) {
pub fn socket_disconnected(&self, descriptor: &Descriptor) {
self.disconnect_event_internal(descriptor, false);
}

Expand DownExpand Up@@ -1073,10 +1077,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
let peers_needing_send = &mut peers.peers_needing_send;
let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
let peers = &mut peers.peers;
let mut descriptors_needing_disconnect = Vec::new();

peers.retain(|descriptor, peer| {
if peer.awaiting_pong {
peers_needing_send.remove(descriptor);
descriptors_needing_disconnect.push(descriptor.clone());
match peer.their_node_id {
Some(node_id) => {
node_id_to_descriptor.remove(&node_id);
Expand DownExpand Up@@ -1104,6 +1110,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
peer.awaiting_pong = true;
true
});

for mut descriptor in descriptors_needing_disconnect.drain(..) {
descriptor.disconnect_socket();
}
}
}
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -217,7 +217,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
// Disconnect all peers
for (idx, peer) in self.peers.borrow().iter().enumerate() {
if *peer {
self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers});
self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers});
}
}

Expand DownExpand Up@@ -378,7 +378,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
2 => {
let peer_id = get_slice!(1)[0];
if !peers.borrow()[peer_id as usize] { return; }
loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers});
peers.borrow_mut()[peer_id as usize] = false;
},
3 => {
Expand Down
4 changes: 2 additions & 2 deletions lightning-net-tokio/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ impl Connection {
return future::Either::A(blocker.then(|_| { Ok(()) }));
}
}
//TODO: There's a race where we don't meet the requirements of disconnect_socket if its
//TODO: There's a race where we don't meet the requirements of socket_disconnected if its
//called right here, after we release the us_ref lock in the scope above, but before we
//call read_event!
match peer_manager.read_event(&mut SocketDescriptor::new(us_ref.clone(), peer_manager.clone()), pending_read) {
Expand All@@ -84,7 +84,7 @@ impl Connection {
future::Either::B(future::result(Ok(())))
}).then(move |_| {
if us_close_ref.lock().unwrap().need_disconnect {
peer_manager_ref.disconnect_event(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
peer_manager_ref.socket_disconnected(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
println!("Peer disconnected!");
} else {
println!("We disconnected peer!");
Expand Down
60 changes: 35 additions & 25 deletions lightning/src/ln/peer_handler.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,12 +49,12 @@ pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandl
/// You probably want to just extend an int and put a file descriptor in a struct and implement
/// send_data. Note that if you are using a higher-level net library that may close() itself, be
/// careful to ensure you don't have races whereby you might register a new connection with an fd
/// the same as a yet-to-be-disconnect_event()-ed.
/// the same as a yet-to-be-socket_disconnected()-ed.
Comment on lines 51 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the emphasized is saying:

whereby you might register a new connection with an fd the same as a yet-to-be-socket_disconnected()-ed.

Something seems grammatically off or perhaps I'm just not parsing this correctly.

pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// Attempts to send some data from the given slice to the peer.
///
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
/// Note that in the disconnected case, a disconnect_event must still fire and further write
/// Note that in the disconnected case, a socket_disconnected must still fire and further write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "a".

/// attempts may occur until that time.
///
/// If the returned size is smaller than data.len(), a write_available event must
Expand All@@ -67,17 +67,18 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// *not* imply that further read events should be paused.
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize;
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
/// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
/// No disconnect_event should be generated as a result of this call, though obviously races
/// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
/// that event completing.
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
/// though obviously races may occur whereby disconnect_socket is called after a call to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "obviously". The reason for including the comment is that this behavior is not obvious.

/// socket_disconnected but prior to that event completing.
Comment on lines -70 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"No disconnect_event" was changed to "No socket_disconnected call" here but later in the comment "event" is still used.

prior to that event completing

Rather than replacing "event" with "call", I'd recommend re-wording to something a little less ambiguous such as:

prior to the former completing

fn disconnect_socket(&mut self);
}

/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
/// generate no further read/write_events for the descriptor, only triggering a single
/// disconnect_event (unless it was provided in response to a new_*_connection event, in which case
/// no such disconnect_event must be generated and the socket be silently disconencted).
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
/// triggering a single socket_disconnected call (unless it was provided in response to a
/// new_*_connection event, in which case no such socket_disconnected() must be generated and the
/// socket be silently disconencted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar: must be

pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
Expand DownExpand Up@@ -201,7 +202,7 @@ macro_rules! encode_msg {
}

/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after disconnect_event() has been called.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where CM::Target: msgs::ChannelMessageHandler {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
Expand DownExpand Up@@ -254,13 +255,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
}

/// Indicates a new outbound connection has been established to a node with the given node_id.
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// Returns a small number of bytes to send to the remote node (currently always 50).
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
/// socket_disconnected().
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
Expand DownExpand Up@@ -294,11 +295,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// call disconnect_event for the new descriptor but must disconnect the connection
/// call socket_disconnected for the new descriptor but must disconnect the connection
/// immediately.
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
/// socket_disconnected called.
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
Expand DownExpand Up@@ -406,10 +407,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
/// new_*\_connection) before returning. Thus, be very careful with reentrancy issues! The
/// invariants around calling write_event in case a write did not fully complete must still
/// hold - be ready to call write_event again if a write call generated here isn't sufficient!
/// Panics if the descriptor was not previously registered in a new_\*_connection event.
pub fn write_event(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
/// new_\*_connection event.
pub fn write_buffer_space_avail(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
let mut peers = self.peers.lock().unwrap();
match peers.peers.get_mut(descriptor) {
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Expand All@@ -429,8 +431,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
/// Thus, however, you almost certainly want to call process_events() after any read_event to
/// generate send_data calls to handle responses.
///
/// If Ok(true) is returned, further read_events should not be triggered until a write_event on
/// this file descriptor has resume_read set (preventing DoS issues in the send buffer).
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
///
/// Panics if the descriptor was not previously registered in a new_*_connection event.
pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec<u8>) -> Result<bool, PeerHandleError> {
Expand DownExpand Up@@ -1036,11 +1038,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where

/// Indicates that the given socket descriptor's connection is now closed.
///
/// This must be called even if a PeerHandleError was given for a read_event or write_event,
/// but must NOT be called if a PeerHandleError was provided out of a new_\*\_connection event!
/// This must only be called if the socket has been disconnected by the peer or your own
/// decision to disconnect it and must NOT be called in any case where other parts of this
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the user supposed to differentiate between their own call to disconnect_socket and that of this library?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, disconnect_socket is different from socket_disconnected - I suppose a user could call disconnect_socket on their own Descriptor, but in general I presumed they wouldn't (and would just call shutdown(2)).

/// the peer.
///
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
pub fn disconnect_event(&self, descriptor: &Descriptor) {
pub fn socket_disconnected(&self, descriptor: &Descriptor) {
self.disconnect_event_internal(descriptor, false);
}

Expand DownExpand Up@@ -1073,10 +1077,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
let peers_needing_send = &mut peers.peers_needing_send;
let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
let peers = &mut peers.peers;
let mut descriptors_needing_disconnect = Vec::new();

peers.retain(|descriptor, peer| {
if peer.awaiting_pong {
peers_needing_send.remove(descriptor);
descriptors_needing_disconnect.push(descriptor.clone());
match peer.their_node_id {
Some(node_id) => {
node_id_to_descriptor.remove(&node_id);
Expand DownExpand Up@@ -1104,6 +1110,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
peer.awaiting_pong = true;
true
});

for mut descriptor in descriptors_needing_disconnect.drain(..) {
descriptor.disconnect_socket();
}
}
}
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -217,7 +217,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
// Disconnect all peers
for (idx, peer) in self.peers.borrow().iter().enumerate() {
if *peer {
self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers});
self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers});
}
}

Expand DownExpand Up@@ -378,7 +378,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
2 => {
let peer_id = get_slice!(1)[0];
if !peers.borrow()[peer_id as usize] { return; }
loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers});
peers.borrow_mut()[peer_id as usize] = false;
},
3 => {
Expand Down
4 changes: 2 additions & 2 deletions lightning-net-tokio/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ impl Connection {
return future::Either::A(blocker.then(|_| { Ok(()) }));
}
}
//TODO: There's a race where we don't meet the requirements of disconnect_socket if its
//TODO: There's a race where we don't meet the requirements of socket_disconnected if its
//called right here, after we release the us_ref lock in the scope above, but before we
//call read_event!
match peer_manager.read_event(&mut SocketDescriptor::new(us_ref.clone(), peer_manager.clone()), pending_read) {
Expand All@@ -84,7 +84,7 @@ impl Connection {
future::Either::B(future::result(Ok(())))
}).then(move |_| {
if us_close_ref.lock().unwrap().need_disconnect {
peer_manager_ref.disconnect_event(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
peer_manager_ref.socket_disconnected(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
println!("Peer disconnected!");
} else {
println!("We disconnected peer!");
Expand Down
60 changes: 35 additions & 25 deletions lightning/src/ln/peer_handler.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,12 +49,12 @@ pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandl
/// You probably want to just extend an int and put a file descriptor in a struct and implement
/// send_data. Note that if you are using a higher-level net library that may close() itself, be
/// careful to ensure you don't have races whereby you might register a new connection with an fd
/// the same as a yet-to-be-disconnect_event()-ed.
/// the same as a yet-to-be-socket_disconnected()-ed.
Comment on lines 51 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the emphasized is saying:

whereby you might register a new connection with an fd the same as a yet-to-be-socket_disconnected()-ed.

Something seems grammatically off or perhaps I'm just not parsing this correctly.

pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// Attempts to send some data from the given slice to the peer.
///
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
/// Note that in the disconnected case, a disconnect_event must still fire and further write
/// Note that in the disconnected case, a socket_disconnected must still fire and further write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "a".

/// attempts may occur until that time.
///
/// If the returned size is smaller than data.len(), a write_available event must
Expand All@@ -67,17 +67,18 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// *not* imply that further read events should be paused.
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize;
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
/// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
/// No disconnect_event should be generated as a result of this call, though obviously races
/// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
/// that event completing.
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
/// though obviously races may occur whereby disconnect_socket is called after a call to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "obviously". The reason for including the comment is that this behavior is not obvious.

/// socket_disconnected but prior to that event completing.
Comment on lines -70 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"No disconnect_event" was changed to "No socket_disconnected call" here but later in the comment "event" is still used.

prior to that event completing

Rather than replacing "event" with "call", I'd recommend re-wording to something a little less ambiguous such as:

prior to the former completing

fn disconnect_socket(&mut self);
}

/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
/// generate no further read/write_events for the descriptor, only triggering a single
/// disconnect_event (unless it was provided in response to a new_*_connection event, in which case
/// no such disconnect_event must be generated and the socket be silently disconencted).
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
/// triggering a single socket_disconnected call (unless it was provided in response to a
/// new_*_connection event, in which case no such socket_disconnected() must be generated and the
/// socket be silently disconencted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar: must be

pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
Expand DownExpand Up@@ -201,7 +202,7 @@ macro_rules! encode_msg {
}

/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after disconnect_event() has been called.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where CM::Target: msgs::ChannelMessageHandler {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
Expand DownExpand Up@@ -254,13 +255,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
}

/// Indicates a new outbound connection has been established to a node with the given node_id.
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// Returns a small number of bytes to send to the remote node (currently always 50).
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
/// socket_disconnected().
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
Expand DownExpand Up@@ -294,11 +295,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// call disconnect_event for the new descriptor but must disconnect the connection
/// call socket_disconnected for the new descriptor but must disconnect the connection
/// immediately.
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
/// socket_disconnected called.
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
Expand DownExpand Up@@ -406,10 +407,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
/// new_*\_connection) before returning. Thus, be very careful with reentrancy issues! The
/// invariants around calling write_event in case a write did not fully complete must still
/// hold - be ready to call write_event again if a write call generated here isn't sufficient!
/// Panics if the descriptor was not previously registered in a new_\*_connection event.
pub fn write_event(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
/// new_\*_connection event.
pub fn write_buffer_space_avail(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
let mut peers = self.peers.lock().unwrap();
match peers.peers.get_mut(descriptor) {
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Expand All@@ -429,8 +431,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
/// Thus, however, you almost certainly want to call process_events() after any read_event to
/// generate send_data calls to handle responses.
///
/// If Ok(true) is returned, further read_events should not be triggered until a write_event on
/// this file descriptor has resume_read set (preventing DoS issues in the send buffer).
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
///
/// Panics if the descriptor was not previously registered in a new_*_connection event.
pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec<u8>) -> Result<bool, PeerHandleError> {
Expand DownExpand Up@@ -1036,11 +1038,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where

/// Indicates that the given socket descriptor's connection is now closed.
///
/// This must be called even if a PeerHandleError was given for a read_event or write_event,
/// but must NOT be called if a PeerHandleError was provided out of a new_\*\_connection event!
/// This must only be called if the socket has been disconnected by the peer or your own
/// decision to disconnect it and must NOT be called in any case where other parts of this
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the user supposed to differentiate between their own call to disconnect_socket and that of this library?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, disconnect_socket is different from socket_disconnected - I suppose a user could call disconnect_socket on their own Descriptor, but in general I presumed they wouldn't (and would just call shutdown(2)).

/// the peer.
///
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
pub fn disconnect_event(&self, descriptor: &Descriptor) {
pub fn socket_disconnected(&self, descriptor: &Descriptor) {
self.disconnect_event_internal(descriptor, false);
}

Expand DownExpand Up@@ -1073,10 +1077,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
let peers_needing_send = &mut peers.peers_needing_send;
let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
let peers = &mut peers.peers;
let mut descriptors_needing_disconnect = Vec::new();

peers.retain(|descriptor, peer| {
if peer.awaiting_pong {
peers_needing_send.remove(descriptor);
descriptors_needing_disconnect.push(descriptor.clone());
match peer.their_node_id {
Some(node_id) => {
node_id_to_descriptor.remove(&node_id);
Expand DownExpand Up@@ -1104,6 +1110,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
peer.awaiting_pong = true;
true
});

for mut descriptor in descriptors_needing_disconnect.drain(..) {
descriptor.disconnect_socket();
}
}
}
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -217,7 +217,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
// Disconnect all peers
for (idx, peer) in self.peers.borrow().iter().enumerate() {
if *peer {
self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers});
self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers});
}
}

Expand DownExpand Up@@ -378,7 +378,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
2 => {
let peer_id = get_slice!(1)[0];
if !peers.borrow()[peer_id as usize] { return; }
loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers});
peers.borrow_mut()[peer_id as usize] = false;
},
3 => {
Expand Down
4 changes: 2 additions & 2 deletions lightning-net-tokio/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ impl Connection {
return future::Either::A(blocker.then(|_| { Ok(()) }));
}
}
//TODO: There's a race where we don't meet the requirements of disconnect_socket if its
//TODO: There's a race where we don't meet the requirements of socket_disconnected if its
//called right here, after we release the us_ref lock in the scope above, but before we
//call read_event!
match peer_manager.read_event(&mut SocketDescriptor::new(us_ref.clone(), peer_manager.clone()), pending_read) {
Expand All@@ -84,7 +84,7 @@ impl Connection {
future::Either::B(future::result(Ok(())))
}).then(move |_| {
if us_close_ref.lock().unwrap().need_disconnect {
peer_manager_ref.disconnect_event(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
peer_manager_ref.socket_disconnected(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
println!("Peer disconnected!");
} else {
println!("We disconnected peer!");
Expand Down
60 changes: 35 additions & 25 deletions lightning/src/ln/peer_handler.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,12 +49,12 @@ pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandl
/// You probably want to just extend an int and put a file descriptor in a struct and implement
/// send_data. Note that if you are using a higher-level net library that may close() itself, be
/// careful to ensure you don't have races whereby you might register a new connection with an fd
/// the same as a yet-to-be-disconnect_event()-ed.
/// the same as a yet-to-be-socket_disconnected()-ed.
Comment on lines 51 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the emphasized is saying:

whereby you might register a new connection with an fd the same as a yet-to-be-socket_disconnected()-ed.

Something seems grammatically off or perhaps I'm just not parsing this correctly.

pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// Attempts to send some data from the given slice to the peer.
///
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
/// Note that in the disconnected case, a disconnect_event must still fire and further write
/// Note that in the disconnected case, a socket_disconnected must still fire and further write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "a".

/// attempts may occur until that time.
///
/// If the returned size is smaller than data.len(), a write_available event must
Expand All@@ -67,17 +67,18 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// *not* imply that further read events should be paused.
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize;
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
/// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
/// No disconnect_event should be generated as a result of this call, though obviously races
/// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
/// that event completing.
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
/// though obviously races may occur whereby disconnect_socket is called after a call to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "obviously". The reason for including the comment is that this behavior is not obvious.

/// socket_disconnected but prior to that event completing.
Comment on lines -70 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"No disconnect_event" was changed to "No socket_disconnected call" here but later in the comment "event" is still used.

prior to that event completing

Rather than replacing "event" with "call", I'd recommend re-wording to something a little less ambiguous such as:

prior to the former completing

fn disconnect_socket(&mut self);
}

/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
/// generate no further read/write_events for the descriptor, only triggering a single
/// disconnect_event (unless it was provided in response to a new_*_connection event, in which case
/// no such disconnect_event must be generated and the socket be silently disconencted).
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
/// triggering a single socket_disconnected call (unless it was provided in response to a
/// new_*_connection event, in which case no such socket_disconnected() must be generated and the
/// socket be silently disconencted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar: must be

pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
Expand DownExpand Up@@ -201,7 +202,7 @@ macro_rules! encode_msg {
}

/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after disconnect_event() has been called.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where CM::Target: msgs::ChannelMessageHandler {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
Expand DownExpand Up@@ -254,13 +255,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
}

/// Indicates a new outbound connection has been established to a node with the given node_id.
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// Returns a small number of bytes to send to the remote node (currently always 50).
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
/// socket_disconnected().
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
Expand DownExpand Up@@ -294,11 +295,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// call disconnect_event for the new descriptor but must disconnect the connection
/// call socket_disconnected for the new descriptor but must disconnect the connection
/// immediately.
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
/// socket_disconnected called.
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
Expand DownExpand Up@@ -406,10 +407,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
/// new_*\_connection) before returning. Thus, be very careful with reentrancy issues! The
/// invariants around calling write_event in case a write did not fully complete must still
/// hold - be ready to call write_event again if a write call generated here isn't sufficient!
/// Panics if the descriptor was not previously registered in a new_\*_connection event.
pub fn write_event(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
/// new_\*_connection event.
pub fn write_buffer_space_avail(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
let mut peers = self.peers.lock().unwrap();
match peers.peers.get_mut(descriptor) {
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Expand All@@ -429,8 +431,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
/// Thus, however, you almost certainly want to call process_events() after any read_event to
/// generate send_data calls to handle responses.
///
/// If Ok(true) is returned, further read_events should not be triggered until a write_event on
/// this file descriptor has resume_read set (preventing DoS issues in the send buffer).
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
///
/// Panics if the descriptor was not previously registered in a new_*_connection event.
pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec<u8>) -> Result<bool, PeerHandleError> {
Expand DownExpand Up@@ -1036,11 +1038,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where

/// Indicates that the given socket descriptor's connection is now closed.
///
/// This must be called even if a PeerHandleError was given for a read_event or write_event,
/// but must NOT be called if a PeerHandleError was provided out of a new_\*\_connection event!
/// This must only be called if the socket has been disconnected by the peer or your own
/// decision to disconnect it and must NOT be called in any case where other parts of this
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the user supposed to differentiate between their own call to disconnect_socket and that of this library?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, disconnect_socket is different from socket_disconnected - I suppose a user could call disconnect_socket on their own Descriptor, but in general I presumed they wouldn't (and would just call shutdown(2)).

/// the peer.
///
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
pub fn disconnect_event(&self, descriptor: &Descriptor) {
pub fn socket_disconnected(&self, descriptor: &Descriptor) {
self.disconnect_event_internal(descriptor, false);
}

Expand DownExpand Up@@ -1073,10 +1077,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
let peers_needing_send = &mut peers.peers_needing_send;
let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
let peers = &mut peers.peers;
let mut descriptors_needing_disconnect = Vec::new();

peers.retain(|descriptor, peer| {
if peer.awaiting_pong {
peers_needing_send.remove(descriptor);
descriptors_needing_disconnect.push(descriptor.clone());
match peer.their_node_id {
Some(node_id) => {
node_id_to_descriptor.remove(&node_id);
Expand DownExpand Up@@ -1104,6 +1110,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
peer.awaiting_pong = true;
true
});

for mut descriptor in descriptors_needing_disconnect.drain(..) {
descriptor.disconnect_socket();
}
}
}
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -217,7 +217,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
// Disconnect all peers
for (idx, peer) in self.peers.borrow().iter().enumerate() {
if *peer {
self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers});
self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers});
}
}

Expand DownExpand Up@@ -378,7 +378,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
2 => {
let peer_id = get_slice!(1)[0];
if !peers.borrow()[peer_id as usize] { return; }
loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers});
peers.borrow_mut()[peer_id as usize] = false;
},
3 => {
Expand Down
4 changes: 2 additions & 2 deletions lightning-net-tokio/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ impl Connection {
return future::Either::A(blocker.then(|_| { Ok(()) }));
}
}
//TODO: There's a race where we don't meet the requirements of disconnect_socket if its
//TODO: There's a race where we don't meet the requirements of socket_disconnected if its
//called right here, after we release the us_ref lock in the scope above, but before we
//call read_event!
match peer_manager.read_event(&mut SocketDescriptor::new(us_ref.clone(), peer_manager.clone()), pending_read) {
Expand All@@ -84,7 +84,7 @@ impl Connection {
future::Either::B(future::result(Ok(())))
}).then(move |_| {
if us_close_ref.lock().unwrap().need_disconnect {
peer_manager_ref.disconnect_event(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
peer_manager_ref.socket_disconnected(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
println!("Peer disconnected!");
} else {
println!("We disconnected peer!");
Expand Down
60 changes: 35 additions & 25 deletions lightning/src/ln/peer_handler.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,12 +49,12 @@ pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandl
/// You probably want to just extend an int and put a file descriptor in a struct and implement
/// send_data. Note that if you are using a higher-level net library that may close() itself, be
/// careful to ensure you don't have races whereby you might register a new connection with an fd
/// the same as a yet-to-be-disconnect_event()-ed.
/// the same as a yet-to-be-socket_disconnected()-ed.
Comment on lines 51 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the emphasized is saying:

whereby you might register a new connection with an fd the same as a yet-to-be-socket_disconnected()-ed.

Something seems grammatically off or perhaps I'm just not parsing this correctly.

pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// Attempts to send some data from the given slice to the peer.
///
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
/// Note that in the disconnected case, a disconnect_event must still fire and further write
/// Note that in the disconnected case, a socket_disconnected must still fire and further write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "a".

/// attempts may occur until that time.
///
/// If the returned size is smaller than data.len(), a write_available event must
Expand All@@ -67,17 +67,18 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// *not* imply that further read events should be paused.
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize;
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
/// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
/// No disconnect_event should be generated as a result of this call, though obviously races
/// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
/// that event completing.
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
/// though obviously races may occur whereby disconnect_socket is called after a call to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "obviously". The reason for including the comment is that this behavior is not obvious.

/// socket_disconnected but prior to that event completing.
Comment on lines -70 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"No disconnect_event" was changed to "No socket_disconnected call" here but later in the comment "event" is still used.

prior to that event completing

Rather than replacing "event" with "call", I'd recommend re-wording to something a little less ambiguous such as:

prior to the former completing

fn disconnect_socket(&mut self);
}

/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
/// generate no further read/write_events for the descriptor, only triggering a single
/// disconnect_event (unless it was provided in response to a new_*_connection event, in which case
/// no such disconnect_event must be generated and the socket be silently disconencted).
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
/// triggering a single socket_disconnected call (unless it was provided in response to a
/// new_*_connection event, in which case no such socket_disconnected() must be generated and the
/// socket be silently disconencted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar: must be

pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
Expand DownExpand Up@@ -201,7 +202,7 @@ macro_rules! encode_msg {
}

/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after disconnect_event() has been called.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where CM::Target: msgs::ChannelMessageHandler {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
Expand DownExpand Up@@ -254,13 +255,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
}

/// Indicates a new outbound connection has been established to a node with the given node_id.
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// Returns a small number of bytes to send to the remote node (currently always 50).
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
/// socket_disconnected().
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
Expand DownExpand Up@@ -294,11 +295,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// call disconnect_event for the new descriptor but must disconnect the connection
/// call socket_disconnected for the new descriptor but must disconnect the connection
/// immediately.
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
/// socket_disconnected called.
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
Expand DownExpand Up@@ -406,10 +407,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
/// new_*\_connection) before returning. Thus, be very careful with reentrancy issues! The
/// invariants around calling write_event in case a write did not fully complete must still
/// hold - be ready to call write_event again if a write call generated here isn't sufficient!
/// Panics if the descriptor was not previously registered in a new_\*_connection event.
pub fn write_event(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
/// new_\*_connection event.
pub fn write_buffer_space_avail(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
let mut peers = self.peers.lock().unwrap();
match peers.peers.get_mut(descriptor) {
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Expand All@@ -429,8 +431,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
/// Thus, however, you almost certainly want to call process_events() after any read_event to
/// generate send_data calls to handle responses.
///
/// If Ok(true) is returned, further read_events should not be triggered until a write_event on
/// this file descriptor has resume_read set (preventing DoS issues in the send buffer).
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
///
/// Panics if the descriptor was not previously registered in a new_*_connection event.
pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec<u8>) -> Result<bool, PeerHandleError> {
Expand DownExpand Up@@ -1036,11 +1038,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where

/// Indicates that the given socket descriptor's connection is now closed.
///
/// This must be called even if a PeerHandleError was given for a read_event or write_event,
/// but must NOT be called if a PeerHandleError was provided out of a new_\*\_connection event!
/// This must only be called if the socket has been disconnected by the peer or your own
/// decision to disconnect it and must NOT be called in any case where other parts of this
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the user supposed to differentiate between their own call to disconnect_socket and that of this library?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, disconnect_socket is different from socket_disconnected - I suppose a user could call disconnect_socket on their own Descriptor, but in general I presumed they wouldn't (and would just call shutdown(2)).

/// the peer.
///
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
pub fn disconnect_event(&self, descriptor: &Descriptor) {
pub fn socket_disconnected(&self, descriptor: &Descriptor) {
self.disconnect_event_internal(descriptor, false);
}

Expand DownExpand Up@@ -1073,10 +1077,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
let peers_needing_send = &mut peers.peers_needing_send;
let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
let peers = &mut peers.peers;
let mut descriptors_needing_disconnect = Vec::new();

peers.retain(|descriptor, peer| {
if peer.awaiting_pong {
peers_needing_send.remove(descriptor);
descriptors_needing_disconnect.push(descriptor.clone());
match peer.their_node_id {
Some(node_id) => {
node_id_to_descriptor.remove(&node_id);
Expand DownExpand Up@@ -1104,6 +1110,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
peer.awaiting_pong = true;
true
});

for mut descriptor in descriptors_needing_disconnect.drain(..) {
descriptor.disconnect_socket();
}
}
}
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -217,7 +217,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
// Disconnect all peers
for (idx, peer) in self.peers.borrow().iter().enumerate() {
if *peer {
self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers});
self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers});
}
}

Expand DownExpand Up@@ -378,7 +378,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
2 => {
let peer_id = get_slice!(1)[0];
if !peers.borrow()[peer_id as usize] { return; }
loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers});
peers.borrow_mut()[peer_id as usize] = false;
},
3 => {
Expand Down
4 changes: 2 additions & 2 deletions lightning-net-tokio/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ impl Connection {
return future::Either::A(blocker.then(|_| { Ok(()) }));
}
}
//TODO: There's a race where we don't meet the requirements of disconnect_socket if its
//TODO: There's a race where we don't meet the requirements of socket_disconnected if its
//called right here, after we release the us_ref lock in the scope above, but before we
//call read_event!
match peer_manager.read_event(&mut SocketDescriptor::new(us_ref.clone(), peer_manager.clone()), pending_read) {
Expand All@@ -84,7 +84,7 @@ impl Connection {
future::Either::B(future::result(Ok(())))
}).then(move |_| {
if us_close_ref.lock().unwrap().need_disconnect {
peer_manager_ref.disconnect_event(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
peer_manager_ref.socket_disconnected(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
println!("Peer disconnected!");
} else {
println!("We disconnected peer!");
Expand Down
60 changes: 35 additions & 25 deletions lightning/src/ln/peer_handler.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,12 +49,12 @@ pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandl
/// You probably want to just extend an int and put a file descriptor in a struct and implement
/// send_data. Note that if you are using a higher-level net library that may close() itself, be
/// careful to ensure you don't have races whereby you might register a new connection with an fd
/// the same as a yet-to-be-disconnect_event()-ed.
/// the same as a yet-to-be-socket_disconnected()-ed.
Comment on lines 51 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the emphasized is saying:

whereby you might register a new connection with an fd the same as a yet-to-be-socket_disconnected()-ed.

Something seems grammatically off or perhaps I'm just not parsing this correctly.

pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// Attempts to send some data from the given slice to the peer.
///
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
/// Note that in the disconnected case, a disconnect_event must still fire and further write
/// Note that in the disconnected case, a socket_disconnected must still fire and further write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "a".

/// attempts may occur until that time.
///
/// If the returned size is smaller than data.len(), a write_available event must
Expand All@@ -67,17 +67,18 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// *not* imply that further read events should be paused.
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize;
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
/// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
/// No disconnect_event should be generated as a result of this call, though obviously races
/// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
/// that event completing.
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
/// though obviously races may occur whereby disconnect_socket is called after a call to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "obviously". The reason for including the comment is that this behavior is not obvious.

/// socket_disconnected but prior to that event completing.
Comment on lines -70 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"No disconnect_event" was changed to "No socket_disconnected call" here but later in the comment "event" is still used.

prior to that event completing

Rather than replacing "event" with "call", I'd recommend re-wording to something a little less ambiguous such as:

prior to the former completing

fn disconnect_socket(&mut self);
}

/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
/// generate no further read/write_events for the descriptor, only triggering a single
/// disconnect_event (unless it was provided in response to a new_*_connection event, in which case
/// no such disconnect_event must be generated and the socket be silently disconencted).
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
/// triggering a single socket_disconnected call (unless it was provided in response to a
/// new_*_connection event, in which case no such socket_disconnected() must be generated and the
/// socket be silently disconencted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar: must be

pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
Expand DownExpand Up@@ -201,7 +202,7 @@ macro_rules! encode_msg {
}

/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after disconnect_event() has been called.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where CM::Target: msgs::ChannelMessageHandler {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
Expand DownExpand Up@@ -254,13 +255,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
}

/// Indicates a new outbound connection has been established to a node with the given node_id.
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// Returns a small number of bytes to send to the remote node (currently always 50).
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
/// socket_disconnected().
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
Expand DownExpand Up@@ -294,11 +295,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// call disconnect_event for the new descriptor but must disconnect the connection
/// call socket_disconnected for the new descriptor but must disconnect the connection
/// immediately.
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
/// socket_disconnected called.
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
Expand DownExpand Up@@ -406,10 +407,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
/// new_*\_connection) before returning. Thus, be very careful with reentrancy issues! The
/// invariants around calling write_event in case a write did not fully complete must still
/// hold - be ready to call write_event again if a write call generated here isn't sufficient!
/// Panics if the descriptor was not previously registered in a new_\*_connection event.
pub fn write_event(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
/// new_\*_connection event.
pub fn write_buffer_space_avail(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
let mut peers = self.peers.lock().unwrap();
match peers.peers.get_mut(descriptor) {
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Expand All@@ -429,8 +431,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
/// Thus, however, you almost certainly want to call process_events() after any read_event to
/// generate send_data calls to handle responses.
///
/// If Ok(true) is returned, further read_events should not be triggered until a write_event on
/// this file descriptor has resume_read set (preventing DoS issues in the send buffer).
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
///
/// Panics if the descriptor was not previously registered in a new_*_connection event.
pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec<u8>) -> Result<bool, PeerHandleError> {
Expand DownExpand Up@@ -1036,11 +1038,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where

/// Indicates that the given socket descriptor's connection is now closed.
///
/// This must be called even if a PeerHandleError was given for a read_event or write_event,
/// but must NOT be called if a PeerHandleError was provided out of a new_\*\_connection event!
/// This must only be called if the socket has been disconnected by the peer or your own
/// decision to disconnect it and must NOT be called in any case where other parts of this
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the user supposed to differentiate between their own call to disconnect_socket and that of this library?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, disconnect_socket is different from socket_disconnected - I suppose a user could call disconnect_socket on their own Descriptor, but in general I presumed they wouldn't (and would just call shutdown(2)).

/// the peer.
///
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
pub fn disconnect_event(&self, descriptor: &Descriptor) {
pub fn socket_disconnected(&self, descriptor: &Descriptor) {
self.disconnect_event_internal(descriptor, false);
}

Expand DownExpand Up@@ -1073,10 +1077,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
let peers_needing_send = &mut peers.peers_needing_send;
let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
let peers = &mut peers.peers;
let mut descriptors_needing_disconnect = Vec::new();

peers.retain(|descriptor, peer| {
if peer.awaiting_pong {
peers_needing_send.remove(descriptor);
descriptors_needing_disconnect.push(descriptor.clone());
match peer.their_node_id {
Some(node_id) => {
node_id_to_descriptor.remove(&node_id);
Expand DownExpand Up@@ -1104,6 +1110,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
peer.awaiting_pong = true;
true
});

for mut descriptor in descriptors_needing_disconnect.drain(..) {
descriptor.disconnect_socket();
}
}
}
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -217,7 +217,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
// Disconnect all peers
for (idx, peer) in self.peers.borrow().iter().enumerate() {
if *peer {
self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers});
self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers});
}
}

Expand DownExpand Up@@ -378,7 +378,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
2 => {
let peer_id = get_slice!(1)[0];
if !peers.borrow()[peer_id as usize] { return; }
loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers});
peers.borrow_mut()[peer_id as usize] = false;
},
3 => {
Expand Down
4 changes: 2 additions & 2 deletions lightning-net-tokio/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ impl Connection {
return future::Either::A(blocker.then(|_| { Ok(()) }));
}
}
//TODO: There's a race where we don't meet the requirements of disconnect_socket if its
//TODO: There's a race where we don't meet the requirements of socket_disconnected if its
//called right here, after we release the us_ref lock in the scope above, but before we
//call read_event!
match peer_manager.read_event(&mut SocketDescriptor::new(us_ref.clone(), peer_manager.clone()), pending_read) {
Expand All@@ -84,7 +84,7 @@ impl Connection {
future::Either::B(future::result(Ok(())))
}).then(move |_| {
if us_close_ref.lock().unwrap().need_disconnect {
peer_manager_ref.disconnect_event(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
peer_manager_ref.socket_disconnected(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
println!("Peer disconnected!");
} else {
println!("We disconnected peer!");
Expand Down
60 changes: 35 additions & 25 deletions lightning/src/ln/peer_handler.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,12 +49,12 @@ pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandl
/// You probably want to just extend an int and put a file descriptor in a struct and implement
/// send_data. Note that if you are using a higher-level net library that may close() itself, be
/// careful to ensure you don't have races whereby you might register a new connection with an fd
/// the same as a yet-to-be-disconnect_event()-ed.
/// the same as a yet-to-be-socket_disconnected()-ed.
Comment on lines 51 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the emphasized is saying:

whereby you might register a new connection with an fd the same as a yet-to-be-socket_disconnected()-ed.

Something seems grammatically off or perhaps I'm just not parsing this correctly.

pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// Attempts to send some data from the given slice to the peer.
///
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
/// Note that in the disconnected case, a disconnect_event must still fire and further write
/// Note that in the disconnected case, a socket_disconnected must still fire and further write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "a".

/// attempts may occur until that time.
///
/// If the returned size is smaller than data.len(), a write_available event must
Expand All@@ -67,17 +67,18 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// *not* imply that further read events should be paused.
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize;
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
/// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
/// No disconnect_event should be generated as a result of this call, though obviously races
/// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
/// that event completing.
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
/// though obviously races may occur whereby disconnect_socket is called after a call to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "obviously". The reason for including the comment is that this behavior is not obvious.

/// socket_disconnected but prior to that event completing.
Comment on lines -70 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"No disconnect_event" was changed to "No socket_disconnected call" here but later in the comment "event" is still used.

prior to that event completing

Rather than replacing "event" with "call", I'd recommend re-wording to something a little less ambiguous such as:

prior to the former completing

fn disconnect_socket(&mut self);
}

/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
/// generate no further read/write_events for the descriptor, only triggering a single
/// disconnect_event (unless it was provided in response to a new_*_connection event, in which case
/// no such disconnect_event must be generated and the socket be silently disconencted).
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
/// triggering a single socket_disconnected call (unless it was provided in response to a
/// new_*_connection event, in which case no such socket_disconnected() must be generated and the
/// socket be silently disconencted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar: must be

pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
Expand DownExpand Up@@ -201,7 +202,7 @@ macro_rules! encode_msg {
}

/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after disconnect_event() has been called.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where CM::Target: msgs::ChannelMessageHandler {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
Expand DownExpand Up@@ -254,13 +255,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
}

/// Indicates a new outbound connection has been established to a node with the given node_id.
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// Returns a small number of bytes to send to the remote node (currently always 50).
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
/// socket_disconnected().
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
Expand DownExpand Up@@ -294,11 +295,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// call disconnect_event for the new descriptor but must disconnect the connection
/// call socket_disconnected for the new descriptor but must disconnect the connection
/// immediately.
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
/// socket_disconnected called.
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
Expand DownExpand Up@@ -406,10 +407,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
/// new_*\_connection) before returning. Thus, be very careful with reentrancy issues! The
/// invariants around calling write_event in case a write did not fully complete must still
/// hold - be ready to call write_event again if a write call generated here isn't sufficient!
/// Panics if the descriptor was not previously registered in a new_\*_connection event.
pub fn write_event(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
/// new_\*_connection event.
pub fn write_buffer_space_avail(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
let mut peers = self.peers.lock().unwrap();
match peers.peers.get_mut(descriptor) {
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Expand All@@ -429,8 +431,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
/// Thus, however, you almost certainly want to call process_events() after any read_event to
/// generate send_data calls to handle responses.
///
/// If Ok(true) is returned, further read_events should not be triggered until a write_event on
/// this file descriptor has resume_read set (preventing DoS issues in the send buffer).
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
///
/// Panics if the descriptor was not previously registered in a new_*_connection event.
pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec<u8>) -> Result<bool, PeerHandleError> {
Expand DownExpand Up@@ -1036,11 +1038,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where

/// Indicates that the given socket descriptor's connection is now closed.
///
/// This must be called even if a PeerHandleError was given for a read_event or write_event,
/// but must NOT be called if a PeerHandleError was provided out of a new_\*\_connection event!
/// This must only be called if the socket has been disconnected by the peer or your own
/// decision to disconnect it and must NOT be called in any case where other parts of this
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the user supposed to differentiate between their own call to disconnect_socket and that of this library?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, disconnect_socket is different from socket_disconnected - I suppose a user could call disconnect_socket on their own Descriptor, but in general I presumed they wouldn't (and would just call shutdown(2)).

/// the peer.
///
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
pub fn disconnect_event(&self, descriptor: &Descriptor) {
pub fn socket_disconnected(&self, descriptor: &Descriptor) {
self.disconnect_event_internal(descriptor, false);
}

Expand DownExpand Up@@ -1073,10 +1077,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
let peers_needing_send = &mut peers.peers_needing_send;
let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
let peers = &mut peers.peers;
let mut descriptors_needing_disconnect = Vec::new();

peers.retain(|descriptor, peer| {
if peer.awaiting_pong {
peers_needing_send.remove(descriptor);
descriptors_needing_disconnect.push(descriptor.clone());
match peer.their_node_id {
Some(node_id) => {
node_id_to_descriptor.remove(&node_id);
Expand DownExpand Up@@ -1104,6 +1110,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
peer.awaiting_pong = true;
true
});

for mut descriptor in descriptors_needing_disconnect.drain(..) {
descriptor.disconnect_socket();
}
}
}
}
Expand Down
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions fuzz/src/full_stack.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -217,7 +217,7 @@ impl<'a> Drop for MoneyLossDetector<'a> {
// Disconnect all peers
for (idx, peer) in self.peers.borrow().iter().enumerate() {
if *peer {
self.handler.disconnect_event(&Peer{id: idx as u8, peers_connected: &self.peers});
self.handler.socket_disconnected(&Peer{id: idx as u8, peers_connected: &self.peers});
}
}

Expand DownExpand Up@@ -378,7 +378,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
2 => {
let peer_id = get_slice!(1)[0];
if !peers.borrow()[peer_id as usize] { return; }
loss_detector.handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
loss_detector.handler.socket_disconnected(&Peer{id: peer_id, peers_connected: &peers});
peers.borrow_mut()[peer_id as usize] = false;
},
3 => {
Expand Down
4 changes: 2 additions & 2 deletions lightning-net-tokio/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -59,7 +59,7 @@ impl Connection {
return future::Either::A(blocker.then(|_| { Ok(()) }));
}
}
//TODO: There's a race where we don't meet the requirements of disconnect_socket if its
//TODO: There's a race where we don't meet the requirements of socket_disconnected if its
//called right here, after we release the us_ref lock in the scope above, but before we
//call read_event!
match peer_manager.read_event(&mut SocketDescriptor::new(us_ref.clone(), peer_manager.clone()), pending_read) {
Expand All@@ -84,7 +84,7 @@ impl Connection {
future::Either::B(future::result(Ok(())))
}).then(move |_| {
if us_close_ref.lock().unwrap().need_disconnect {
peer_manager_ref.disconnect_event(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
peer_manager_ref.socket_disconnected(&SocketDescriptor::new(us_close_ref, peer_manager_ref.clone()));
println!("Peer disconnected!");
} else {
println!("We disconnected peer!");
Expand Down
60 changes: 35 additions & 25 deletions lightning/src/ln/peer_handler.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,12 +49,12 @@ pub struct MessageHandler<CM: Deref> where CM::Target: msgs::ChannelMessageHandl
/// You probably want to just extend an int and put a file descriptor in a struct and implement
/// send_data. Note that if you are using a higher-level net library that may close() itself, be
/// careful to ensure you don't have races whereby you might register a new connection with an fd
/// the same as a yet-to-be-disconnect_event()-ed.
/// the same as a yet-to-be-socket_disconnected()-ed.
Comment on lines 51 to +52

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand what the emphasized is saying:

whereby you might register a new connection with an fd the same as a yet-to-be-socket_disconnected()-ed.

Something seems grammatically off or perhaps I'm just not parsing this correctly.

pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// Attempts to send some data from the given slice to the peer.
///
/// Returns the amount of data which was sent, possibly 0 if the socket has since disconnected.
/// Note that in the disconnected case, a disconnect_event must still fire and further write
/// Note that in the disconnected case, a socket_disconnected must still fire and further write

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "a".

/// attempts may occur until that time.
///
/// If the returned size is smaller than data.len(), a write_available event must
Expand All@@ -67,17 +67,18 @@ pub trait SocketDescriptor : cmp::Eq + hash::Hash + Clone {
/// *not* imply that further read events should be paused.
fn send_data(&mut self, data: &[u8], resume_read: bool) -> usize;
/// Disconnect the socket pointed to by this SocketDescriptor. Once this function returns, no
/// more calls to write_event, read_event or disconnect_event may be made with this descriptor.
/// No disconnect_event should be generated as a result of this call, though obviously races
/// may occur whereby disconnect_socket is called after a call to disconnect_event but prior to
/// that event completing.
/// more calls to write_buffer_space_avail, read_event or socket_disconnected may be made with
/// this descriptor. No socket_disconnected call should be generated as a result of this call,
/// though obviously races may occur whereby disconnect_socket is called after a call to

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop "obviously". The reason for including the comment is that this behavior is not obvious.

/// socket_disconnected but prior to that event completing.
Comment on lines -70 to +73

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"No disconnect_event" was changed to "No socket_disconnected call" here but later in the comment "event" is still used.

prior to that event completing

Rather than replacing "event" with "call", I'd recommend re-wording to something a little less ambiguous such as:

prior to the former completing

fn disconnect_socket(&mut self);
}

/// Error for PeerManager errors. If you get one of these, you must disconnect the socket and
/// generate no further read/write_events for the descriptor, only triggering a single
/// disconnect_event (unless it was provided in response to a new_*_connection event, in which case
/// no such disconnect_event must be generated and the socket be silently disconencted).
/// generate no further read_event/write_buffer_space_avail calls for the descriptor, only
/// triggering a single socket_disconnected call (unless it was provided in response to a
/// new_*_connection event, in which case no such socket_disconnected() must be generated and the
/// socket be silently disconencted).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

grammar: must be

pub struct PeerHandleError {
/// Used to indicate that we probably can't make any future connections to this peer, implying
/// we should go ahead and force-close any channels we have with it.
Expand DownExpand Up@@ -201,7 +202,7 @@ macro_rules! encode_msg {
}

/// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds.
/// PeerIds may repeat, but only after disconnect_event() has been called.
/// PeerIds may repeat, but only after socket_disconnected() has been called.
impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where CM::Target: msgs::ChannelMessageHandler {
/// Constructs a new PeerManager with the given message handlers and node_id secret key
/// ephemeral_random_data is used to derive per-connection ephemeral keys and must be
Expand DownExpand Up@@ -254,13 +255,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
}

/// Indicates a new outbound connection has been established to a node with the given node_id.
/// Note that if an Err is returned here you MUST NOT call disconnect_event for the new
/// Note that if an Err is returned here you MUST NOT call socket_disconnected for the new
/// descriptor but must disconnect the connection immediately.
///
/// Returns a small number of bytes to send to the remote node (currently always 50).
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had a
/// socket_disconnected().
pub fn new_outbound_connection(&self, their_node_id: PublicKey, descriptor: Descriptor) -> Result<Vec<u8>, PeerHandleError> {
let mut peer_encryptor = PeerChannelEncryptor::new_outbound(their_node_id.clone(), self.get_ephemeral_key());
let res = peer_encryptor.get_act_one().to_vec();
Expand DownExpand Up@@ -294,11 +295,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// May refuse the connection by returning an Err, but will never write bytes to the remote end
/// (outbound connector always speaks first). Note that if an Err is returned here you MUST NOT
/// call disconnect_event for the new descriptor but must disconnect the connection
/// call socket_disconnected for the new descriptor but must disconnect the connection
/// immediately.
///
/// Panics if descriptor is duplicative with some other descriptor which has not yet has a
/// disconnect_event.
/// Panics if descriptor is duplicative with some other descriptor which has not yet had
/// socket_disconnected called.
pub fn new_inbound_connection(&self, descriptor: Descriptor) -> Result<(), PeerHandleError> {
let peer_encryptor = PeerChannelEncryptor::new_inbound(&self.our_node_secret);
let pending_read_buffer = [0; 50].to_vec(); // Noise act one is 50 bytes
Expand DownExpand Up@@ -406,10 +407,11 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
///
/// Will most likely call send_data on the descriptor passed in (or the descriptor handed into
/// new_*\_connection) before returning. Thus, be very careful with reentrancy issues! The
/// invariants around calling write_event in case a write did not fully complete must still
/// hold - be ready to call write_event again if a write call generated here isn't sufficient!
/// Panics if the descriptor was not previously registered in a new_\*_connection event.
pub fn write_event(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
/// invariants around calling write_buffer_space_avail in case a write did not fully complete
/// must still hold - be ready to call write_buffer_space_avail again if a write call generated
/// here isn't sufficient! Panics if the descriptor was not previously registered in a
/// new_\*_connection event.
pub fn write_buffer_space_avail(&self, descriptor: &mut Descriptor) -> Result<(), PeerHandleError> {
let mut peers = self.peers.lock().unwrap();
match peers.peers.get_mut(descriptor) {
None => panic!("Descriptor for write_event is not already known to PeerManager"),
Expand All@@ -429,8 +431,8 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
/// Thus, however, you almost certainly want to call process_events() after any read_event to
/// generate send_data calls to handle responses.
///
/// If Ok(true) is returned, further read_events should not be triggered until a write_event on
/// this file descriptor has resume_read set (preventing DoS issues in the send buffer).
/// If Ok(true) is returned, further read_events should not be triggered until a send_data call
/// on this file descriptor has resume_read set (preventing DoS issues in the send buffer).
///
/// Panics if the descriptor was not previously registered in a new_*_connection event.
pub fn read_event(&self, peer_descriptor: &mut Descriptor, data: Vec<u8>) -> Result<bool, PeerHandleError> {
Expand DownExpand Up@@ -1036,11 +1038,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where

/// Indicates that the given socket descriptor's connection is now closed.
///
/// This must be called even if a PeerHandleError was given for a read_event or write_event,
/// but must NOT be called if a PeerHandleError was provided out of a new_\*\_connection event!
/// This must only be called if the socket has been disconnected by the peer or your own
/// decision to disconnect it and must NOT be called in any case where other parts of this
/// library (eg PeerHandleError, explicit disconnect_socket calls) instruct you to disconnect

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the user supposed to differentiate between their own call to disconnect_socket and that of this library?

Copy link
Copy Markdown
CollaboratorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, disconnect_socket is different from socket_disconnected - I suppose a user could call disconnect_socket on their own Descriptor, but in general I presumed they wouldn't (and would just call shutdown(2)).

/// the peer.
///
/// Panics if the descriptor was not previously registered in a successful new_*_connection event.
pub fn disconnect_event(&self, descriptor: &Descriptor) {
pub fn socket_disconnected(&self, descriptor: &Descriptor) {
self.disconnect_event_internal(descriptor, false);
}

Expand DownExpand Up@@ -1073,10 +1077,12 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
let peers_needing_send = &mut peers.peers_needing_send;
let node_id_to_descriptor = &mut peers.node_id_to_descriptor;
let peers = &mut peers.peers;
let mut descriptors_needing_disconnect = Vec::new();

peers.retain(|descriptor, peer| {
if peer.awaiting_pong {
peers_needing_send.remove(descriptor);
descriptors_needing_disconnect.push(descriptor.clone());
match peer.their_node_id {
Some(node_id) => {
node_id_to_descriptor.remove(&node_id);
Expand DownExpand Up@@ -1104,6 +1110,10 @@ impl<Descriptor: SocketDescriptor, CM: Deref> PeerManager<Descriptor, CM> where
peer.awaiting_pong = true;
true
});

for mut descriptor in descriptors_needing_disconnect.drain(..) {
descriptor.disconnect_socket();
}
}
}
}
Expand Down