#define TCP_PATH_MTU \
( 1280 - 40 /* IPv6 */ - 20 /* TCP */ - 12 /* TCP timestamp */ )
-/**
- * Advertised TCP MSS
- *
- * We currently hardcode this to a reasonable value and hope that the
- * sender uses path MTU discovery. The alternative is breaking the
- * abstraction layer so that we can find out the MTU from the IP layer
- * (which would have to find out from the net device layer).
- */
-#define TCP_MSS 1460
-
/** TCP maximum segment lifetime
*
* Currently set to 2 minutes, as per RFC 793.
struct sockaddr_tcpip peer;
/** Local port */
unsigned int local_port;
+ /** Maximum segment size */
+ size_t mss;
/** Current TCP state */
unsigned int tcp_state;
struct sockaddr_tcpip *st_peer = ( struct sockaddr_tcpip * ) peer;
struct sockaddr_tcpip *st_local = ( struct sockaddr_tcpip * ) local;
struct tcp_connection *tcp;
+ size_t mtu;
int port;
int rc;
INIT_LIST_HEAD ( &tcp->rx_queue );
memcpy ( &tcp->peer, st_peer, sizeof ( tcp->peer ) );
+ /* Calculate MSS */
+ mtu = tcpip_mtu ( &tcp->peer );
+ if ( ! mtu ) {
+ DBGC ( tcp, "TCP %p has no route to %s\n",
+ tcp, sock_ntoa ( peer ) );
+ rc = -ENETUNREACH;
+ goto err;
+ }
+ tcp->mss = ( mtu - sizeof ( struct tcp_header ) );
+
/* Bind to local port */
port = tcpip_bind ( st_local, tcp_port_available );
if ( port < 0 ) {
mssopt = iob_push ( iobuf, sizeof ( *mssopt ) );
mssopt->kind = TCP_OPTION_MSS;
mssopt->length = sizeof ( *mssopt );
- mssopt->mss = htons ( TCP_MSS );
+ mssopt->mss = htons ( tcp->mss );
wsopt = iob_push ( iobuf, sizeof ( *wsopt ) );
wsopt->nop = TCP_OPTION_NOP;
wsopt->wsopt.kind = TCP_OPTION_WS;