Browse Source

lnmsg: add details to FailedToParseMsg, log message type

note: Would it be ok to log potentially secret (semi-sensitive) data?
We take care not to log onchain private keys as they are extremely sensitive,
but what about logging a LN transport message that might contain channel secrets?
Decided not to, for now.
master
SomberNight 3 years ago
parent
commit
ab953f4a7f
No known key found for this signature in database
GPG Key ID: B33B5F232C6271E9
  1. 63
      electrum/lnmsg.py
  2. 10
      electrum/lnpeer.py

63
electrum/lnmsg.py

@ -7,7 +7,9 @@ from collections import OrderedDict
from .lnutil import OnionFailureCodeMetaFlag
class FailedToParseMsg(Exception): pass
class FailedToParseMsg(Exception):
msg_type_int: Optional[int] = None
msg_type_name: Optional[str] = None
class UnknownMsgType(FailedToParseMsg): pass
class UnknownOptionalMsgType(UnknownMsgType): pass
@ -488,33 +490,38 @@ class LNSerializer:
assert scheme[0][2] == msg_type_int
msg_type_name = scheme[0][1]
parsed = {}
with io.BytesIO(data[2:]) as fd:
for row in scheme:
#print(f"row: {row!r}")
if row[0] == "msgtype":
pass
elif row[0] == "msgdata":
field_name = row[2]
field_type = row[3]
field_count_str = row[4]
field_count = _resolve_field_count(field_count_str, vars_dict=parsed)
if field_name == "tlvs":
tlv_stream_name = field_type
d = self.read_tlv_stream(fd=fd, tlv_stream_name=tlv_stream_name)
parsed[tlv_stream_name] = d
continue
#print(f">> count={field_count}. parsed={parsed}")
try:
parsed[field_name] = _read_field(fd=fd,
field_type=field_type,
count=field_count)
except UnexpectedEndOfStream as e:
if len(row) > 5:
break # optional feature field not present
else:
raise
else:
raise Exception(f"unexpected row in scheme: {row!r}")
try:
with io.BytesIO(data[2:]) as fd:
for row in scheme:
#print(f"row: {row!r}")
if row[0] == "msgtype":
pass
elif row[0] == "msgdata":
field_name = row[2]
field_type = row[3]
field_count_str = row[4]
field_count = _resolve_field_count(field_count_str, vars_dict=parsed)
if field_name == "tlvs":
tlv_stream_name = field_type
d = self.read_tlv_stream(fd=fd, tlv_stream_name=tlv_stream_name)
parsed[tlv_stream_name] = d
continue
#print(f">> count={field_count}. parsed={parsed}")
try:
parsed[field_name] = _read_field(fd=fd,
field_type=field_type,
count=field_count)
except UnexpectedEndOfStream as e:
if len(row) > 5:
break # optional feature field not present
else:
raise
else:
raise Exception(f"unexpected row in scheme: {row!r}")
except FailedToParseMsg as e:
e.msg_type_int = msg_type_int
e.msg_type_name = msg_type_name
raise
return msg_type_name, parsed

10
electrum/lnpeer.py

@ -45,7 +45,7 @@ from .lnutil import (Outpoint, LocalConfig, RECEIVED, UpdateAddHtlc, ChannelConf
ChannelType, LNProtocolWarning)
from .lnutil import FeeUpdate, channel_id_from_funding_tx
from .lntransport import LNTransport, LNTransportBase
from .lnmsg import encode_msg, decode_msg, UnknownOptionalMsgType
from .lnmsg import encode_msg, decode_msg, UnknownOptionalMsgType, FailedToParseMsg
from .interface import GracefulDisconnect
from .lnrouter import fee_for_edge_msat
from .lnutil import ln_dummy_address
@ -194,12 +194,18 @@ class Peer(Logger):
self.pong_event.clear()
await self.pong_event.wait()
def process_message(self, message):
def process_message(self, message: bytes):
try:
message_type, payload = decode_msg(message)
except UnknownOptionalMsgType as e:
self.logger.info(f"received unknown message from peer. ignoring: {e!r}")
return
except FailedToParseMsg as e:
self.logger.info(
f"failed to parse message from peer. disconnecting. "
f"msg_type={e.msg_type_name}({e.msg_type_int}). exc={e!r}")
#self.logger.info(f"failed to parse message: message(SECRET?)={message.hex()}")
raise GracefulDisconnect() from e
self.last_message_time = time.time()
if message_type not in self.SPAMMY_MESSAGES:
self.logger.debug(f"Received {message_type.upper()}")

Loading…
Cancel
Save