Sending TCP frames of fixed length
Asked Answered
C

4

5

I need to send some data over the subnet with fixed non-standard MTU (for example, 1560) using TCP. All the Ethernet frames transfered through this subnet should be manually padded with 0's, if the frame's length is less than MTU.

So, the data size should be (1560 - sizeof( IP header ) - sizeof( TCP header ) ).

This is the way I am going to do it:

  1. I set the TCP_CORK option to decrease the fragmenting of data. It is not reliable, because there is 200 millisecond ceiling, but it works.

  2. I know size of IP header (20 bytes), so data length should be equal to (1540 - sizeof( TCP header )).

  3. That's the problem. I don't know the TCP header size. The size of it's "Options" field is floating.

So, the question is: how to get the size of TCP header? Or maybe there is some way to send TCP frames with headers of fixed length?

Copter answered 31/5, 2011 at 14:29 Comment(13)
Isn't regular Ethernet's max frame size 1,538 bytes (including Ethernet overhead)?Chordate
If you want fixed-length frames, are you sure you shouldn't be using UDP?Retraction
1. It is. But it is regular max frame size. In any case, the precise value of MTU doesn't matter in this case. 2. I'm afraid I can't. I haven't mentioned it, but there is also HTTP over TCP.Copter
Have to agree, this sounds like a Bad Idea. But, I'm curious why you believe you require this??Timeless
Because the system administrator believes it. I want to discuss it with my supervisor, but he is absent right now, so I decided do ask some questions here.Copter
The proper answer is no, my application will not pad ethernet frames; that function belongs to the ethernet drivers. Your system admin is off his rocker if he thinks all TCP frames need to be at MTU size. Why should we pad TCP SYN and FIN packets with zeros? It is absurd to send more data than you need... it increases network utilization for no good reason. Ignore him, seriously. Mike (who has been a Cisco CCIE for ten years and spends all day testing networks)Jimmiejimmy
@unwind, Ethernet MTUs exceed 9000 bytes in some cases, but there is no standard way to handle frames larger than 1522 bytes (which includes the dest mac-addr and 4-byte CRC). The preamble, SFD, and IFG are never counted as real data by most practicionersJimmiejimmy
@Platinum Azure, UDP is the wrong way to solve this problem; many protocols depend solely on TCP (like HTTP, FTP, SSH, etc...). Furthermore, the whole idea is just dumb. There is no other word for it... don't entertain the folly of fools.Jimmiejimmy
@Mike Pennington: It's not a dumb idea. It guarantees packet length. It just has tradeoffs, like any other protocol choice. If you want absolute reliability, then yes, you want TCP. But you can write a scheme in UDP that acts like TCP if you really want to. It just takes a little more effort.Retraction
@Platinum Azure, it is a dumb idea if there is no compelling reason for fixed-length ethernet frames. As of now, there has been none stated, other than the capricious decision of an (apparently) un-enlightened LAN administrator.Jimmiejimmy
@Mike Pennington: Then that's your issue. Talk to the OP and/or his/her network administrator. My suggestion DOES answer to the requirement of fixed-length ethernet frames. I'm sorry that the mere fact of the OP asking for fixed-length frames isn't a good enough reason for you to overcome your prejudice against them and against UDP. Your replies have been very unprofessional and I think you should take a good look at why you're here and how you should be reacting to questions with which you find issue.Retraction
@Platinum Azure, you said UDP is not a dumb idea; I explained why it is. We can disagree. I will examine my motivation for being here. You are 22 years old and (at best) fresh out of college. Perhaps you could examine the reality that I have been maintaining networks professionally since you were 6 years old and might have a little more experience to evaluate the suitability of a UDP solution. As for my reactions, on rare occasions it is suitable to say "WTF". This is one, in my opinion... if you don't like that, we will also disagree on that point.Jimmiejimmy
@Mike Pennington: Okay, I didn't see the earlier comments about the sysadmin wanting it, so now I agree with your response. I had taken issue with the tone of your reply. I still have an issue with that but factually it is clear to me that you are correct. I thought there might have been a domain-specific reason for wanting fixed-length frames (in which case, I'm sure you'll agree that UDP is one possible solution-- iff you're willing to trade away reliability and packet ordering). I apologize for taking your comment out of context. I still think your tone is unnecessarily cutting.Retraction
P
10

Trying to control the size of frames when using TCP from the user application is wrong. You are working at the wrong abstraction level. It's also impossible.

What you should be doing is either consider replacing TCP with something else (UDP?) or, less likely, but possible, rewrite your Ethernet driver to set the non standard MTU and do the padding you need.

Parchment answered 31/5, 2011 at 14:43 Comment(4)
Okay, thanks for the answer. That's right, trying to control the size of Ethernet frames from TCP level is wrong, but I hoped that there is a way to do it.Copter
Have you tried a "raw" socket interface? It allows you to define the entire packet within your program, though it may still require the size to be within that of an Ethernet MTU (which may be changeable via "ifconfig").Peerage
Yes, the one way to do it is to use raw sockets. But I am too lazy to create TCP headers manually =) If I don't find another way, I will have to use raw sockets.Copter
But why do you need to create these ethernet frames based on what you send as data on top of TCP ? If you want efficiency, you don't need to do anything, TCP will take care of that. If you want to use a non-standard MTU, you really need to configure the MTU on the network interface, which is system wide. If you're somehow tunelling stuff on top a TCP connection, you'll need to come up with your own framing for transferring packets over TCP. If you're doing network testing, there's many tools around to aid you.Turfman
D
6

This isn't possible using the TCP stack of the host simply because a TCP stack that follows RFC 793 isn't supposed to offer this kind of access to an application.

That is, there isn't (and there shouldn't be) a way to influence what the lower layers do with your data. Of course, there are ways to influence what TCP does (Nagle for example) but that is against the spirit of the protocol. TCP should be used for what it's best at: transferring a continuous, ordered stream of bytes. Nothing more, nothing less. No messages, packets, frames.

If after all you do need to control such details, you need to look at lower-level APIs. You could use SOCK_RAW and PF_PACKET.

Packet sockets are used to receive or send raw packets at the device driver (OSI Layer 2) level.

@gby mentioned UDP and that is (partially) a good idea: UDP has a fixed size. But keep in mind that you will have to deal with IP fragmentation (or use IP_DONTFRAG).

Dhahran answered 31/5, 2011 at 14:59 Comment(0)
J
2

In addition to my comments below the OP's question, this quote from the original RFC outlining how to send TCP/IP over ethernet is relevant:

RFC 894 (emphasis mine): If necessary, the data field should be padded (with octets of zero) to meet the Ethernet minimum frame size.

If they wanted all ethernet frames to be at maximum size, they would have said so. They did not.

Jimmiejimmy answered 31/5, 2011 at 17:30 Comment(0)
D
0

Maybe what was meant by padding is that the TCP header padding to align it on 32 bits should be all zeros : http://freesoft.org/CIE/Course/Section4/8.htm

Dynamiter answered 29/4, 2015 at 16:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.