I am able to gain the mss value from getsockopt
:
tcpmss.c:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdio.h>
int main()
{
int sockfd, mss;
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
perror("sockfd");
return 1;
}
socklen_t len = sizeof(mss);
if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len) < 0)
{
perror("getsockopt");
return 1;
}
printf("maximum segment size: %d\n", mss);
}
output:
maximum segment size: 536
other sources says, the default mss is 1460
. But If I try to check it from client:
client.c:
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#define GET_CMD "GET %s HTTP/1.0\r\n\r\n"
#define SERV "80"
#define HOST "google.com"
#define HOMEPG "/"
//BUFSIZ = 8192, defined in <stdio.h>
int main()
{
int sockfd, nbytes;
struct addrinfo hints, *res;
char buf[BUFSIZ];
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(HOST, SERV, &hints, &res) != 0)
{
perror("getaddrinfo");
return 1;
}
if ((sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
{
perror("socket");
return 1;
}
if (connect(sockfd, res->ai_addr, res->ai_addrlen) < 0)
{
perror("connect");
return 1;
}
nbytes = snprintf(buf, 256, GET_CMD, HOMEPG);
if (write(sockfd, buf, nbytes) < 0)
{
perror("write");
return 1;
}
while ((nbytes = read(sockfd, buf, BUFSIZ)) > 0)
{
printf("read %d bytes of home page of %s\n", nbytes, HOST);
}
if (nbytes == 0)
{
printf("got EOF from google.com");
}
}
output:
read 8192 bytes of home page of google.com
read 3888 bytes of home page of google.com
read 7248 bytes of home page of google.com
read 4832 bytes of home page of google.com
read 6040 bytes of home page of google.com
read 6040 bytes of home page of google.com
read 6040 bytes of home page of google.com
read 4832 bytes of home page of google.com
read 2229 bytes of home page of google.com
got EOF from google.com
neither of those value is true. So I am little bit confuse with maximum segment size. I know the read()
block and fetches more tcp
segments into kernel receive buffer so I cannot see the true segment size from read()
syscall, however, how to determine then the agreed window
between the peers which should correspond to the MSS. Here on the first read()
, I got full buffer, (BUFSIZE == 8192), then not even half, etc.
How to determine (all from my example)
- MSS
- propagated window between peers (and its relation to MSS)
- how much segment size changes between each send operation (and why)