> > I agree that drafts running into such issues have to address this -
> > but this seems possible and is just a design detail that has to be
> > solved.
> 
> I think we are basically in agreement.  This has to be added to the
> list
> of things to check in any tcpinc draft, but we should anticipate that
> it
> is a tractable problem.
> 
> > I still don't understand how this can be an issue if the actual
> buffer
> > and possibly RWND considers the encoding overhead.
> 
> It doesn't have to be an issue, but it can be an issue if a protocol is
> not properly designed.  And naively attempting to address the problem
> could lead to other issues (such as exceeding the receive buffer size).

Sorry, I still don't understand what buffer problem you refer to, assuming the 
protocol design is bug-free. Could you please expand a bit?

> For example, one naive way to solve the problem is to implement payload
> integrity entirely on top of TCP, almost at a different level of
> abstraction.  Something like TLS already works over TCP, so intuitively
> one might expect this to work.

What deadlock is caused when we would use something like TLS for 
confidentiality and something like TCP-AO integrity (or TCP-AO for both)?

> Well obviously not because now the MACs
> are going to consume options space and cause deadlock in situations
> where TCP would have been fine.  Okay, so the next thing one might try

Maybe it would help to me to better understand the deadlock if I had a concrete 
example.

> to do is increase the effective send buffer size to be SO_SNDBUF plus
> the size of all buffered MACs.  But this still doesn't solve the

As far as I know, SO_SNDBUF/SO_RCVBUF is the *socket* buffer size, which should 
not be affected if tcpinc offers a socket interface to the app, as far as I 
understand it.

But the socket buffer may not be the buffer TCP uses - if they were the same, 
this would be a specific implementation choice.

The TCP buffer can be larger. For instance, I think Linux uses for TCP 
buffering a buffer significantly larger than the socket buffer:

      SO_SNDBUF
              Sets or gets the maximum socket send buffer in bytes.  The
              kernel doubles this value (to allow space for bookkeeping
              overhead) when it is set using setsockopt(2), and this doubled
              value is returned by getsockopt(2).  The default value is set
              by the /proc/sys/net/core/wmem_default file and the maximum
              allowed value is set by the /proc/sys/net/core/wmem_max file.
              The minimum (doubled) value for this option is 2048.

       SO_RCVBUF
              Sets or gets the maximum socket receive buffer in bytes.  The
              kernel doubles this value (to allow space for bookkeeping
              overhead) when it is set using setsockopt(2), and this doubled
              value is returned by getsockopt(2).  The default value is set
              by the /proc/sys/net/core/rmem_default file, and the maximum
              allowed value is set by the /proc/sys/net/core/rmem_max file.
              The minimum (doubled) value for this option is 256.

Thus, as far as I understand it, the value of SO_RCVBUF is by and large 
decoupled from the TCP receiver advertised window. An application cannot expect 
that the receiver advertised window is equal to SO_RCVBUF etc.

> problem, because now what if the MAC is computed over more data than
> the
> receive window size?  Now the receiver will have a bunch of data whose
> integrity is unknown, and will not have buffer space to receive the
> MAC.

If the MAC for header fields is added in a TCP option (e.g., TCP-AO), I don't 
understand why buffer space would be a problem.

I understand that securing certain TCP header fields from within the TCP byte 
stream may be challenging. But buffer space is by far not the only challenge 
for this, as far as I can see.

> Okay so now allow sender to exceed the receive window and have the
> receiver buffer data until the next MAC.  Okay, but now an ill-behaved
> sender could create a giant message that massively exceeds the receive
> buffer size.

I don't understand why one would have to allow a sender to exceed the receive 
window. Could you please explain why this would be required? It violates the 
TCP specs.
 
> These are all obvious straw-men.  But the point is that the real
> solution is a bit more complicated.  Since as far as I know none of the
> sequence-number-stretching tcpinc proposals has even been implemented,
> it's an open question how exactly flow control interacts with such
> proposals.

tcpcrypt seems to have to violate TCP flow control for INIT1/INIT2 (well, using 
EDO could possibly solve this problem).

Again, please help me better understanding why flow control would be an issue 
in any other solution. We don't need an implementation to understand whether 
protocol semantics are violated or not. But you have to explicitly state your 
assumptions and reason why there is no alternative to them.

> > I think most TCP stacks don't run a static, fixed TCP buffer of size
> > SO_SNDBUF or SO_RCVBUF anyway. In particular packet-based stacks
> seems
> > to work differently internally.
> 
> I haven't tested recently, but in my experience SO_RCVBUF definitely
> impacted the receive window.  More importantly, though, even
> applications that don't set SO_RCVBUF can reasonably assume they get
> some sane default value, meaning at least 4 MSS and less than infinity.

As far as I can tell, the IETF does not mandate how a TCP stack allocates 
buffer internally, nor how it sets the TCP receive window.

> If tcpinc changes this so the effective receive buffer is tiny, it
> could
> cause deadlock.  If tcpinc changes it so the effective receive buffer
> is
> infinity, this breaks flow control.  And obviously, while greater than
> the buffer size, we want some kind of limit on how much buffer space
> the
> kernel needs on the sender or receiver.

Sorry, I cannot follow. It is up to the TCP stack to decide how much buffer to 
allocate, and what receive window to announce.  A TCP stack does not have to 
use SO_RCVBUF for calculating the receive window, as far as I know.

The tcpinc WG may have to specify that a stack has to ensure that the TCP 
buffer is larger than the socket buffer, or the tcpinc WG may specify that a 
TCP endpoint using tcpinc must allocate X additional bytes e.g. to store 
out-of-band key/MAC data, and fall back to vanilla TCP if no RAM us available. 
Why is this a problem?

> > There may be (legacy) middleboxes (PEPs) that send such Pre-ACKs if
> > they know/assume that the path between the middlebox and the receiver
> > is entirely reliable. This is a violation of TCP end-to-end semantics
> > and probably not a PEP behavior that the IETF recommends. But, in
> > particular in satellite environments, this could be a mechanism used
> > for traffic engineering or performance optimization (I've read about
> > it one decade ago, maybe those PEPs went away in the mean time). If
> > used for performance tuning, these ACKs would not be a malicious
> > attack.
> 
> Probably better just to terminate the TCP connection, no?  Particularly
> given the prevalence of transparent proxies.  If there's a choice
> between breaking flow control and slightly diminishing the throughput
> of
> legacy devices that are new enough to use tcpcrypt but not to increase
> their receive buffer size, I would prefer the latter.

Pre-ACKs have been suggested in the past because of the huge RTT in satellite 
networks. This large RTT also affects congestion control (e.g., during 
Slow-Start). The performance difference could be significant.

I agree that a transparent TCP proxy may end up in less issues. Also, I have no 
data whether there are indeed middleboxes in the Internet not terminating the 
connection but faking ACKs. And none of these middleboxes are desirable 
regarding end-to-end TCP semantics. But we have toaccept that people may deploy 
middleboxes e.g. in satellite networks without having attacks in mind.

> > If an attacker that can inject ACKs into the connection, that
> attacker
> > could also send RST or other segments with more impact than a faked
> > ACK, right? So, this is basically a variant of the question whether
> to
> > protect against RST (e.g., with TCP-AO)?
> 
> Well, you can say it's a variant of RST, but the consequences of the
> attack are different and the defenses are different, so it doesn't seem
> that useful to lump them together.  RST protection can be implemented
> locally and unilaterally for a variety of TCP modifications.  Checking
> the integrity of ACKs requires specific support from the wire format.
> 
> Also, RST kills the connection, so it's basically a DoS attack.  ACK
> forgery causes the application to think things are okay, but return
> incorrect values for things like percent complete and bytes/second.

TCP does not guarantee that data indeed arrives at the receiving application. 
TCP only guarantees delivery to the receiving TCP stack. Thus, an application 
that cares about payload integrity (in your example: complete upload) has to 
verify the byte stream at application level for standard TCP already. In that 
case, one can detect that attack already at application level, right? So, I 
really wonder faking a complete upload at TCP level is a real problem.

In addition, one could very easily detect this attack in many scenarios. If an 
application reports an upload rate of 42 Gbit/s on a 4 Mbit/s DSL uplink, that 
would certainly be strange, right? In other words: ACK forgery would have to 
detect the real path capacity in order to keep the displayed throughput without 
reasonable limits of the true value. Getting this right would be quite some 
effort; it seems basically equivalent to an active on-path attacker. Is this 
really what a tcpinc solution should focus on?

Michael

_______________________________________________
Tcpinc mailing list
[email protected]
https://www.ietf.org/mailman/listinfo/tcpinc

Reply via email to