blob: 098004e04145cd8be5e3f0e9e94086edfec5390a [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001
2#include "socketHelper.h"
3#include "util.h"
4
5void close_one_socket(int sock)
6{
7 int ret;
8 if (sock != INVALID_SOCKET) {
9 ret = close(sock);
10 WARN_errno(ret == SOCKET_ERROR, "close socket failed");
11 sock = INVALID_SOCKET;
12 }
13}
14
15void SockAddr_setHostname(const char* inHostname, zping_sockaddr_t *inSockAddr)
16{
17 int rc = inet_pton(AF_INET, inHostname,
18 (void*) & (((struct sockaddr_in*)inSockAddr)->sin_addr));
19 inSockAddr->sin_family = AF_INET;
20 if (rc != 1) {
21 fprintf(stderr, "invalid address: %s\n", inHostname);
22 exit(1);
23 }
24}
25
26int setsock_tcp_windowsize(int inSock, int inTCPWin, int inSend)
27{
28#ifdef SO_SNDBUF
29 int rc;
30 int newTCPWin;
31
32 assert(inSock >= 0);
33
34 if (inTCPWin > 0) {
35
36#ifdef TCP_WINSHIFT
37
38 /* UNICOS requires setting the winshift explicitly */
39 if (inTCPWin > 65535) {
40 int winShift = 0;
41 int scaledWin = inTCPWin >> 16;
42 while (scaledWin > 0) {
43 scaledWin >>= 1;
44 winShift++;
45 }
46
47 /* set TCP window shift */
48 rc = setsockopt(inSock, IPPROTO_TCP, TCP_WINSHIFT,
49 (char*) &winShift, sizeof(winShift));
50 if (rc < 0) {
51 return rc;
52 }
53
54 /* Note: you cannot verify TCP window shift, since it returns
55 * a structure and not the same integer we use to set it. (ugh) */
56 }
57#endif /* TCP_WINSHIFT */
58
59#ifdef TCP_RFC1323
60 /* On AIX, RFC 1323 extensions can be set system-wide,
61 * using the 'no' network options command. But we can also set them
62 * per-socket, so let's try just in case. */
63 if (inTCPWin > 65535) {
64 /* enable RFC 1323 */
65 int on = 1;
66 rc = setsockopt(inSock, IPPROTO_TCP, TCP_RFC1323,
67 (char*) &on, sizeof(on));
68 if (rc < 0) {
69 return rc;
70 }
71 }
72#endif /* TCP_RFC1323 */
73
74 if (!inSend) {
75 /* receive buffer -- set
76 * note: results are verified after connect() or listen(),
77 * since some OS's don't show the corrected value until then. */
78 newTCPWin = inTCPWin;
79 rc = setsockopt(inSock, SOL_SOCKET, SO_RCVBUF,
80 (char*) &newTCPWin, sizeof(newTCPWin));
81 } else {
82 /* send buffer -- set
83 * note: results are verified after connect() or listen(),
84 * since some OS's don't show the corrected value until then. */
85 newTCPWin = inTCPWin;
86 rc = setsockopt(inSock, SOL_SOCKET, SO_SNDBUF,
87 (char*) &newTCPWin, sizeof(newTCPWin));
88 }
89 if (rc < 0) {
90 return rc;
91 }
92 }
93#endif /* SO_SNDBUF */
94
95 return 0;
96} /* end setsock_tcp_windowsize */
97
98const char warn_mss_fail[] = "\
99WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\
100Setting the MSS may not be implemented on this OS.\n";
101
102const char warn_mss_notset[] =
103 "WARNING: attempt to set TCP maximum segment size to %d, but got %d\n";
104
105void setsock_tcp_mss(int inSock, int inMSS)
106{
107#ifdef TCP_MAXSEG
108 int rc;
109 int newMSS;
110 int len;
111
112 assert(inSock != INVALID_SOCKET);
113
114 if (inMSS > 0) {
115 /* set */
116 newMSS = inMSS;
117 len = sizeof(newMSS);
118 rc = setsockopt(inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, len);
119 if (rc == SOCKET_ERROR) {
120 fprintf(stderr, warn_mss_fail, newMSS);
121 return;
122 }
123
124 /* verify results */
125 rc = getsockopt(inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, &len);
126 WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG");
127 if (newMSS != inMSS) {
128 fprintf(stderr, warn_mss_notset, inMSS, newMSS);
129 }
130 }
131#endif
132} /* end setsock_tcp_mss */