/* Initialize module */ void __attribute__ ((constructor)) _init(void) { int opt = 1; struct sockaddr_in sin; orig_sendto = preload("sendto"); orig_recvfrom = preload("recvfrom"); orig_setsockopt = preload("setsockopt"); orig_bind = preload("bind"); ctrl_socket = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (ctrl_socket < 0) { printf ("Ajil lib failed to create control socket\n"); exit (-1); } orig_setsockopt (ctrl_socket, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); memset (&sin, 0, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = inet_addr(DADDRESS); sin.sin_port = htons(DPORT); if (connect (ctrl_socket, (struct sockaddr *) &sin, sizeof(struct sockaddr_in)) < 0) { printf ("Could not connect to Ajil daemon\n"); exit (-1); } else { printf ("Connected to Ajil daemon\n"); usleep (500); if (recv (ctrl_socket, (void *) &data_port, sizeof(uint16_t), 0) < 0) { printf ("Error receiving port number from daemon\n"); exit (-1); } } }
INTERPOSE (setsockopt, int, int sockfd, int level, int optname, const void *optval, socklen_t optlen) { CHECK_INTERPOSE (setsockopt); if (!is_our_fd (sockfd)) return orig_setsockopt (sockfd, level, optname, optval, optlen); if ((level == SOL_SOCKET) && (optname == SO_KEEPALIVE)) { /* Can be safely ignored */ return 0; } if ((level == SOL_SOCKET) && (optname == SO_REUSEADDR)) { //FIXME return 0; } if ((level == SOL_SOCKET) && (optname == SO_LINGER)) { //FIXME return 0; } if ((level == IPPROTO_IP) && (optname == IP_PKTINFO)) { //FIXME return 0; } if ((level == IPPROTO_IP) && (optname == IP_TOS)) { /* Can be safely ignored */ return 0; } if ((level == IPPROTO_IP) && (optname == IP_TTL)) { /* Can be safely ignored */ return 0; } if ((level == IPPROTO_TCP) && (optname == TCP_NODELAY)) { //FIXME return 0; } DEBUG_PRINTF ("unknown setsockopt %d %d %d %p %d\n", sockfd, level, optname, optval, optlen); errno = ENOPROTOOPT; return -1; }
/* Overload setsockopt */ int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) { printf("Called setsockopt\n"); return orig_setsockopt(s, level, optname, optval, optlen); }