2

I'm writing some server software that upgrades the firmware on an electronic device. It's a tricky task, because currently these devices don't have enough memory to hold a full firmware before installing it. As a result my server will switch the device into boot loader mode, and instruct the boot loader what to do, sending instructions and firmware data over the network. As you can imagine, there are some potentially massive downsides to this.

What I'm concerned with at the moment, is whether or not a single TCP segment that I send will be divided up across multiple Ethernet frames?

Due to the nature of the boot loader, the maximum size payload I can send in a TCP segment is 255 bytes.

From grabbing packets in Wireshark, it seems like the Frame size for a frame containing one of my TCP segments is 309 bytes (2,472 bits), well within the range allowed according to the Wikipedia page on Ethernet Frames :

Ethernet Type 2 Frame Format

I'm currently trying to handle what happens if the connection to the device is severed. As things are now I have no trouble reestablishing a connection with a device, but what I want to be sure of is what happens after a connection is reestablished.

If I can be sure that each instruction will always be contained in a single Ethernet frame, and as such, will either be delivered or won't be delivered then happy days! I can look at the last instruction sent and figure out what to do then.

However, if there's a possibility that the instruction can be split across two Ethernet frames then I have a much bigger problem. I don't think it should happen, but it sometimes looks like it does when I'm testing.

Say I have issued a write command, and the boot loader is waiting for data to write, I send my TCP segment with 255 bytes and it gets split across two Ethernet frames. The first frame gets delivered but the second one doesn't. Now when I reconnect I have to figure out exactly how many bytes the boot loader has already received, which means I need to push dummy data and listen for a response. I'd really like to avoid that if possible.

Reading from the comments in this thread, it seems that IP packets smaller than 576 bytes (4,608 bits) won't be split up. Am I safe in assuming that this is always the case?

Actually, If it is split up, then the WiFi module shouldn't deliver the TCP segment until it has been re-assembled, isn't that correct? And it will be discarded if the connection is lost.

5
  • 1
    You can set the DF bit in the IP header. You could always use PMTUD to determine, first, if the MTU in the path is big enough.
    – Ron Maupin
    Mar 3, 2016 at 22:15
  • 1
    Also, when IP packets are fragmented (frames don't get split, packets do, resulting in multiple frames on the new link after the router fragments the packet), it is up to the receiving host to reassemble the packet fragments, per RFC 791. Routers will fragment packets, if necessary, for the MTU of the next link, but they will not reassemble the fragments. A Wi-Fi AP is merely a translating bridge which converts ethernet frames into Wi-Fi frames, and vice versa.
    – Ron Maupin
    Mar 4, 2016 at 7:33
  • Thanks again! Just looking at Wireshark here and the DF bit is already set in the packets
    – mal
    Mar 4, 2016 at 8:08
  • 1
    If the DF bit is set, then the IP packets are not being fragmented. They would, instead, be dropped, and an ICMP message returned to the sender.
    – Ron Maupin
    Mar 4, 2016 at 8:11
  • Thanks for your help, that's one thing clarified, and one less thing to worry about.
    – mal
    Mar 4, 2016 at 8:14

1 Answer 1

1

In general it's very hard to control wether a packet get's split or not. You would need to get very deep on the stack actually - things like offloading TCP to hardware may also get into the way and create packets that are optimised for transportation.

But you're talking about a TCP connection - so there shouldn't be any issue if your connection has a short interrupt. If a single TCP packet get's split into multiple ethernet packets and your connection drops (for a short moment) in between the transmission of a single frame, TCP will retry to transmit the packet (which is part of the protocol).

Having a longer / detected disconnect, a much bigger issue will be the fact, that you can't just continue sending without reestablishing a new connection (which would need your device to support this) - setting up a new socket and sending to the same remote host without TCP syn/ack is propably not supported by any default stack.

Regarding your desired goal (if possible) i would recommend to have a proper way to handle interruptions during the firmware upgrade (like dual boot).

If this is not possible and you're not implementing your own TCP/IP stack, i just can recommend to disable any hardware accelation on your server (to prevent hardware from reassembling your packets) and disable nagle's alogorithm on your socket connection.

4
  • Hi Daniel, thanks for your answer. The situation I'm concerned with is indeed a longer disconnect. currently my server disconnects after a 4 second timeout. The device is capable of re-establishing a connection in this scenario, it's WiFi module handles that automatically, so that isn't a problem, in fact when testing we've rebooted the server and still successfully managed to continue flashing.I suppose, since TCP is an extremely robust protocol it might be in our interests to extend the timeout period on both ends of the connection a bit just in case. Can you elaborate a little on dual boot?
    – mal
    Mar 4, 2016 at 7:25
  • 1
    Depending on the microcontroller running on the device, you can have two seperate locations for your runtime image on the same device (let's say you split your storage into two parts) and when your current firmware is on the first half, you write the new firmware to the second one. final step of flash is to change the pointer of the current firmware to the second half (the pointer should be in a single location that can be written in one step). If flashing fails, you will still boot from the first / old firmware. Mar 4, 2016 at 7:45
  • Ah yes, we don't have enough memory for that right now, currently we're wiping the old firmware before pushing the new one. We will be increasing the memory in the next hardware version for this very reason.
    – mal
    Mar 4, 2016 at 7:47
  • 1
    Another option is to make sure that your bootloader with a minimal network stack - just enough for flashing is always available. So - if you're in flash mode and reboot, you always can restart the procedure. This is something like dual boot, just that the second image is just the bootloader which may be much smaller (depending on your hardware this may fit). Mar 4, 2016 at 8:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .