- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在开发一个接受 HTTP 请求并将它们转发到目的地的项目。我们使用 Linux (2.6.35.14-106.fc14.x86_64) 和 TPROXY。我将在下面提供详细信息。
我看到的问题是,Linux 偶尔(1000 次中有 1 次,有时是 100 万次中有 1 次)将对等地址作为目标地址返回。
有人见过这种情况吗?我在 2007 年在网上看到了一篇笔记,所以我认为它可能有点过时了。
我有以下代码(请原谅此处显示的方法不一致):
struct sockaddr clientaddr;
socklen_t clientlen = sizeof(clientaddr);
int status = getpeername(acceptedSocket, &clientaddr, &clientlen);
char clientName[256];
clientName[0] = '\0';
int clientport = 0;
if (status == 0) {
inet_ntop(AF_INET, (void *) &((struct sockaddr_in *)&clientaddr)->sin_addr, clientName, 256);
clientport = ntohs(((struct sockaddr_in *)& clientaddr)->sin_port);
**printf("Socket::acceptConnection: getpeername : %s:%d\n", clientName, clientport); fflush(stdout);**
}
else
{
LOGINFO(WARNING(352), "Socket::acceptConnection: Could not get client from accepted socket.\n");
}
status = getsockopt(acceptedSocket, SOL_IP, SO_ORIGINAL_DST, (struct sockaddr *) &destaddr, &destlen);
if (status == 0) {
inet_ntop(AF_INET, (void *) &destaddr.sin_addr, destinationName, 256);
int portnumber = ntohs(destaddr.sin_port);
ssize_t dl = strlen(destinationName);
sprintf(&destinationName[dl], ":%d", portnumber);
**printf("Socket::acceptConnection: getsockopt : %s\n", destinationName); fflush(stdout);**
}
else
{
LOGINFO(WARNING(352), "Socket::acceptConnection: Could not get destination from accepted socket.\n");
}
发生的事情是 大多数 getpeername 和 getsockopt 报告正确(参见下面的 IPTABLE 配置)。
不幸的是,偶尔得到的 getsockopt 报告与 getpeername 相同,即目的地与对等点相同。
IPTABLE 配置:
-A PREROUTING -p tcp -m socket -j DIVERT
-A PREROUTING -s 10.2.0.203/32 -p tcp -m tcp --dport 80 -j TPROXY --on-port 8080 --on-ip 10.2.0.204 --tproxy-mark 0x1/0xffffffff
-A DIVERT -j MARK --set-xmark 0x1/0xffffffff
-A DIVERT -j ACCEPT
我们已经记录了事件,看起来没问题。例如,我们得到以下输出:
Socket::acceptConnection: getpeername : 10.2.0.203:48517
Socket::acceptConnection: getsockopt : 10.2.0.203:48517
然而 IPTables 的日志显示 IP 地址是正确的:
Jul 9 17:37:06 2U-204 kernel: [258876.105481] IN=eth3 OUT= MAC=00:1b:21:61:03:99:00:1b:21:61:c0:70:08:00 **SRC=10.2.0.203 DST=192.168.200.206** LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=56054 DF PROTO=TCP **SPT=48517 DPT=80** WINDOW=17896 RES=0x00 SYN URGP=0
Jul 9 17:37:06 2U-204 kernel: [258876.105697] IN=eth3 OUT= MAC=00:1b:21:61:03:99:00:1b:21:61:c0:70:08:00 **SRC=10.2.0.203 DST=192.168.200.206** LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=56055 DF PROTO=TCP **SPT=48517 DPT=80** WINDOW=35 RES=0x00 ACK URGP=0
我真的被这个难住了。
最佳答案
为什么要使用 getsockopt( ... SOL_IP, SO_ORIGINAL_DST ... )
? AFAIK SO_ORIGINAL_DST
旨在与 NAT REDIRECT
目标一起使用,而不是 TPROXY
。
尝试使用简单的 getsockname()
代替。
关于c++ - getsockopt(...,SO_ORIGINAL_DST,...) 偶尔会返回客户端地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11417187/
第三方库仅向我们提供了在其上监听数据的已创建套接字。现在,此套接字可以是udp或tcp, 我不知道应该为getsockopt提供哪些选项来确定套接字是udp还是tcp。 SOL_SOCKET,SO_B
我得到以下链接:SOL_SOCKET in getsockopt() 但这对我来说真的很困惑。有人回答说SOL_SOCKET表示套接字层。什么是套接字层?该参数还有其他可用选项吗? 如果我们传递 SO
我们可以看到api定义为blow int getsockopt(int sockfd, int level, int optname, void *optva
我遇到了 Windows 上套接字的问题。调用 getsockopt() 总是失败。奇怪的是 setsockopt() 似乎有效(至少它报告成功......虽然我设置的选项似乎没有我预期的效果)。 我
我正在开发一个接受 HTTP 请求并将它们转发到目的地的项目。我们使用 Linux (2.6.35.14-106.fc14.x86_64) 和 TPROXY。我将在下面提供详细信息。 我看到的问题是,
我将我的项目从 python tornado 重写为 go(使用 iris 框架)。基本功能测试正常。我在高并发下测试的时候,app总是停一会,然后报错: (dial tcp 192.168.1.22
我正在尝试将gitlab-runner与docker-ssh结合使用。这是我的config.toml的样子: [[runners]] name = “CI/CD docker-ssh alfa” ur
我正在努力了解如何在 kubernetes 1.10 上使用 flannel 正确配置 kube-dns,并将 containerd 作为 CRI。 kube-dns 无法运行,出现以下错误: kub
在 Prometheus 的目标页面中,我收到以下错误: 我在 Linux 主机上使用它 普罗米修斯版本: prometheus, version 1.1.2 (branch: master, rev
我正在尝试增加用于与 Linux 设备驱动程序交互的原始套接字的 SO_RCVBUF。默认的 rmem_default/rmem_max 都太小了,163840。因此我使用以下 stack overf
我浏览了文档,但仍然不明白 optlen 在 getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) ,谁
我正在使用以下程序来调试一个更大的问题。 现在,如果我在 OSX 上运行相同的程序,getopt 永远不会返回 0 或 1,它总是返回我为 optval 设置的任何值!! 一定是我的程序中有明显的错误
OS X 不提供 SO_PROTOCOL 套接字选项,该选项允许调用者“...将套接字类型检索为整数”。 ( http://linux.die.net/man/7/socket ) 换句话说,以下程序
我正在学习 Udacity 的 kubernetes 教程。当我使用以下命令运行 nginx 镜像时 kubectl run nginx --image=nginx:1.10.0 它给了我错误 err
我想从我的 kurnetes 集群中使用我的 etcd pod 的 etcdctl 功能,但我不能。我已经从 kubeadm 安装了我的 kubernetes,我有 1 个主节点和 1 个节点。 当我
当我尝试从私有(private) Docker Registry 中拉取镜像时出现错误 Error response from daemon: Get https://XX.XX.XX.XXX:500
我试图通过在设置后回读它来验证我的 TCP_NODELAY 设置是否有效。 我将值设置为“1”,但当我读回它时,它设置为“4”。恐怕我做错了什么。 这是我的代码: int tcpBefore;
我正在尝试在 GNU/Linux 系统上以编程方式配置我的 TCP 连接的 MSS,特别是 Ubuntu 12.04,内核 3.2.0-68-通用 根据 man 7 tcp TCP_MAXSEG Th
您好,我有以下程序来检查 UDP 套接字的发送缓冲区大小。但是,我的返回值让我有点困惑。我使用以下简单的应用程序: #include #include int main(int argc, cha
套接字选项特别用于什么,即套接字编程中的 setsockopt() 和 getsockopt()? 最佳答案 例如你想设置或知道接收缓冲区大小 1) int skt, int sndsize; err
我是一名优秀的程序员,十分优秀!