I am writing the following program (though I don't think that this is where the problem is):
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int sock=socket(AF_INET, SOCK_STREAM, 0);
if( sock<0 ) {
perror("socket creation failed");
return 1;
}
int ip_transparent_enabled = 1;
if( setsockopt(sock, IPPROTO_IP, IP_TRANSPARENT, &ip_transparent_enabled, sizeof(ip_transparent_enabled))<0 ) {
perror("Setting IP_TRANSPARENT failed");
return 1;
}
struct sockaddr_in bind_addr = { AF_INET, htons(31337) };
inet_aton("93.184.216.34", &bind_addr.sin_addr); // example.com
if( bind(sock, (const struct sockaddr *)&bind_addr, sizeof(bind_addr))<0 ) {
perror("bind failed");
return 1;
}
struct sockaddr_in dest = { AF_INET, htons(7007) };
inet_aton("127.0.0.1", &dest.sin_addr);
if( connect(sock, (const struct sockaddr *)&dest, sizeof(dest))<0 ) {
perror("Connect failed");
return 1;
}
}
Port 7007 is running an echo server, but it's not important, because the program there never receives the connection.
When I run tcpdump, I see that the SYN is sent with the correct (made up) source address, but SYN+ACK is issued on neither loopback nor eth0:
$ sudo tcpdump -i any port 31337
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked), capture size 262144 bytes
22:22:41.475942 IP 93.184.216.34.31337 > localhost.afs3-bos: Flags [S], seq 2953286612, win 65495, options [mss 65495,sackOK,TS val 443673031 ecr 0,nop,wscale 7], length 0
22:22:42.478172 IP 93.184.216.34.31337 > localhost.afs3-bos: Flags [S], seq 2953286612, win 65495, options [mss 65495,sackOK,TS val 443674033 ecr 0,nop,wscale 7], length 0
22:22:44.494174 IP 93.184.216.34.31337 > localhost.afs3-bos: Flags [S], seq 2953286612, win 65495, options [mss 65495,sackOK,TS val 443676049 ecr 0,nop,wscale 7], length 0
22:22:48.590423 IP 93.184.216.34.31337 > localhost.afs3-bos: Flags [S], seq 2953286612, win 65495, options [mss 65495,sackOK,TS val 443680145 ecr 0,nop,wscale 7], length 0
If I comment out the bind
, then everything works as expected. There is no firewall port that seems relevant, and rp_filter
is set to 0 on loopback.
Why is the connection not accepted? Is this an error in my code, or is this configuration related?