blob: 098004e04145cd8be5e3f0e9e94086edfec5390a [file] [log] [blame]
#include "socketHelper.h"
#include "util.h"
void close_one_socket(int sock)
{
int ret;
if (sock != INVALID_SOCKET) {
ret = close(sock);
WARN_errno(ret == SOCKET_ERROR, "close socket failed");
sock = INVALID_SOCKET;
}
}
void SockAddr_setHostname(const char* inHostname, zping_sockaddr_t *inSockAddr)
{
int rc = inet_pton(AF_INET, inHostname,
(void*) & (((struct sockaddr_in*)inSockAddr)->sin_addr));
inSockAddr->sin_family = AF_INET;
if (rc != 1) {
fprintf(stderr, "invalid address: %s\n", inHostname);
exit(1);
}
}
int setsock_tcp_windowsize(int inSock, int inTCPWin, int inSend)
{
#ifdef SO_SNDBUF
int rc;
int newTCPWin;
assert(inSock >= 0);
if (inTCPWin > 0) {
#ifdef TCP_WINSHIFT
/* UNICOS requires setting the winshift explicitly */
if (inTCPWin > 65535) {
int winShift = 0;
int scaledWin = inTCPWin >> 16;
while (scaledWin > 0) {
scaledWin >>= 1;
winShift++;
}
/* set TCP window shift */
rc = setsockopt(inSock, IPPROTO_TCP, TCP_WINSHIFT,
(char*) &winShift, sizeof(winShift));
if (rc < 0) {
return rc;
}
/* Note: you cannot verify TCP window shift, since it returns
* a structure and not the same integer we use to set it. (ugh) */
}
#endif /* TCP_WINSHIFT */
#ifdef TCP_RFC1323
/* On AIX, RFC 1323 extensions can be set system-wide,
* using the 'no' network options command. But we can also set them
* per-socket, so let's try just in case. */
if (inTCPWin > 65535) {
/* enable RFC 1323 */
int on = 1;
rc = setsockopt(inSock, IPPROTO_TCP, TCP_RFC1323,
(char*) &on, sizeof(on));
if (rc < 0) {
return rc;
}
}
#endif /* TCP_RFC1323 */
if (!inSend) {
/* receive buffer -- set
* note: results are verified after connect() or listen(),
* since some OS's don't show the corrected value until then. */
newTCPWin = inTCPWin;
rc = setsockopt(inSock, SOL_SOCKET, SO_RCVBUF,
(char*) &newTCPWin, sizeof(newTCPWin));
} else {
/* send buffer -- set
* note: results are verified after connect() or listen(),
* since some OS's don't show the corrected value until then. */
newTCPWin = inTCPWin;
rc = setsockopt(inSock, SOL_SOCKET, SO_SNDBUF,
(char*) &newTCPWin, sizeof(newTCPWin));
}
if (rc < 0) {
return rc;
}
}
#endif /* SO_SNDBUF */
return 0;
} /* end setsock_tcp_windowsize */
const char warn_mss_fail[] = "\
WARNING: attempt to set TCP maxmimum segment size to %d failed.\n\
Setting the MSS may not be implemented on this OS.\n";
const char warn_mss_notset[] =
"WARNING: attempt to set TCP maximum segment size to %d, but got %d\n";
void setsock_tcp_mss(int inSock, int inMSS)
{
#ifdef TCP_MAXSEG
int rc;
int newMSS;
int len;
assert(inSock != INVALID_SOCKET);
if (inMSS > 0) {
/* set */
newMSS = inMSS;
len = sizeof(newMSS);
rc = setsockopt(inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, len);
if (rc == SOCKET_ERROR) {
fprintf(stderr, warn_mss_fail, newMSS);
return;
}
/* verify results */
rc = getsockopt(inSock, IPPROTO_TCP, TCP_MAXSEG, (char*) &newMSS, &len);
WARN_errno(rc == SOCKET_ERROR, "getsockopt TCP_MAXSEG");
if (newMSS != inMSS) {
fprintf(stderr, warn_mss_notset, inMSS, newMSS);
}
}
#endif
} /* end setsock_tcp_mss */