aboutsummaryrefslogtreecommitdiff
path: root/sshnodelay.c
blob: e1d9220e8c2333cff852d8b776f5a06ec554b690 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#define _GNU_SOURCE
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

#if __APPLE__

int custom_connect(int sock, const struct sockaddr *addr, socklen_t addrlen);

typedef struct interpose_s {
	void *new_func;
	void *orig_func;
} interpose_t;

static const interpose_t interposers[] \
	__attribute__ ((section("__DATA, __interpose"))) = {
	{ (void *)custom_connect,  (void *)connect  },
};

int custom_connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
	int res = connect(sock, addr, addrlen);
	if (!res && addr->sa_family == AF_INET) {
		int opt = 1;
		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
	}
	return res;
}

#else /* !__APPLE__ */

int connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
{
	int (*next_connect)(int, const struct sockaddr *, socklen_t) =
		dlsym(RTLD_NEXT, "connect");
	int res = next_connect(sock, addr, addrlen);
	if (!res && addr->sa_family == AF_INET) {
		int opt = 1;
		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
	}
	return res;
}

#endif /* !__APPLE__ */