From 8771a50b1472e3c6da757b3f5c1da5817bbe592b Mon Sep 17 00:00:00 2001 From: Andrew Bettison Date: Tue, 23 Apr 2013 16:02:39 +0930 Subject: [PATCH] Fix TTL out-of-range bug Was causing two routing tests to fail since the TTL decrement logic was fixed in a8b88a46 The default TTL of 64 overflowed the 5-bit unsigned int in the MDP packet header --- constants.h | 5 +++++ overlay_address.c | 2 +- overlay_mdp.c | 12 +++++++++--- overlay_packetformats.c | 14 ++++++++------ overlay_payload.c | 7 +++++-- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/constants.h b/constants.h index 4f426d34..0ade09f3 100644 --- a/constants.h +++ b/constants.h @@ -100,6 +100,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define PAYLOAD_FLAG_CIPHERED (1<<4) #define PAYLOAD_FLAG_SIGNED (1<<5) +/* Time-to-live is a 'uint5_t'. + */ +#define PAYLOAD_TTL_MAX (31) +#define PAYLOAD_TTL_DEFAULT (31) + // return codes for parsing mdp packet headers #define HEADER_PROCESS 1 #define HEADER_FORWARD 2 diff --git a/overlay_address.c b/overlay_address.c index 1d2aadd2..16982bc2 100644 --- a/overlay_address.c +++ b/overlay_address.c @@ -362,7 +362,7 @@ int send_please_explain(struct decode_context *context, struct subscriber *sourc frame->destination = destination; if (destination && (destination->reachable & REACHABLE)){ - frame->ttl=64; + frame->ttl = PAYLOAD_TTL_DEFAULT; // MAX? }else{ frame->ttl=1;// how will this work with olsr?? overlay_broadcast_generate_address(&frame->broadcast_id); diff --git a/overlay_mdp.c b/overlay_mdp.c index efe58a92..584d9b1f 100644 --- a/overlay_mdp.c +++ b/overlay_mdp.c @@ -626,9 +626,15 @@ int overlay_mdp_dispatch(overlay_mdp_frame *mdp,int userGeneratedFrameP, frame->destination = find_subscriber(mdp->out.dst.sid, SID_SIZE, 1); } - frame->ttl=mdp->out.ttl; - if (frame->ttl==0) - frame->ttl=64; /* default TTL */ + frame->ttl = mdp->out.ttl; + if (frame->ttl == 0) + frame->ttl = PAYLOAD_TTL_DEFAULT; + else if (frame->ttl > PAYLOAD_TTL_MAX) { + op_free(frame); + RETURN(overlay_mdp_reply_error(mdp_named.poll.fd, + recvaddr,recvaddrlen,9, + "TTL out of range")); + } if (!frame->destination || frame->destination->reachable == REACHABLE_SELF) { diff --git a/overlay_packetformats.c b/overlay_packetformats.c index 8aede502..7c31c450 100644 --- a/overlay_packetformats.c +++ b/overlay_packetformats.c @@ -143,7 +143,8 @@ int overlay_forward_payload(struct overlay_frame *f){ // Parse the mdp envelope header // may return (HEADER_PROCESS|HEADER_FORWARD) || -1 int parseMdpPacketHeader(struct decode_context *context, struct overlay_frame *frame, - struct overlay_buffer *buffer, struct subscriber **nexthop){ + struct overlay_buffer *buffer, struct subscriber **nexthop) +{ IN(); int process=1; int forward=2; @@ -203,21 +204,22 @@ int parseMdpPacketHeader(struct decode_context *context, struct overlay_frame *f } } - if (flags & PAYLOAD_FLAG_ONE_HOP){ + if (flags & PAYLOAD_FLAG_ONE_HOP) { frame->ttl=1; - }else{ + } else { int ttl_qos = ob_get(buffer); if (ttl_qos<0) RETURN(WHY("Unable to read ttl")); frame->ttl = ttl_qos & 0x1F; frame->queue = (ttl_qos >> 5) & 3; } - if (frame->ttl == 0){ + if (frame->ttl) + --frame->ttl; + if (frame->ttl == 0) { forward = 0; if (config.debug.overlayframes) DEBUGF("Don't forward when TTL expired"); - } else - --frame->ttl; + } if (flags & PAYLOAD_FLAG_LEGACY_TYPE){ int ftype = ob_get(buffer); diff --git a/overlay_payload.c b/overlay_payload.c index 89380d9a..9c6e3066 100644 --- a/overlay_payload.c +++ b/overlay_payload.c @@ -26,8 +26,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. int overlay_frame_build_header(struct decode_context *context, struct overlay_buffer *buff, int queue, int type, int modifiers, int ttl, struct broadcast *broadcast, struct subscriber *next_hop, - struct subscriber *destination, struct subscriber *source){ - + struct subscriber *destination, struct subscriber *source) +{ + if (ttl < 0 || ttl > PAYLOAD_TTL_MAX) + return WHYF("invalid ttl=%d", ttl); + int flags = modifiers & (PAYLOAD_FLAG_CIPHERED | PAYLOAD_FLAG_SIGNED); if (ttl==1 && !broadcast)