服务启动过程中,偶然间看到udp socket发送报文,出现 errno == 1 错误码。
错误码对应的描述:
出现错误的代码,在失败后,下次定时尝试重作,无权限问题不出现了,具有偶发性!
在服务器启动过程中发送网络报文,出现errno == 1错误,最开始执拗于udp socket是无连接的协议,只要目的地址正确,而且有响应的路由,都应该可以发送的,觉得不应该出现此类错误?
而且,在网上搜索,此类错误码等于‘1’的场景描述也较少。
为了具体而微地解剖这个问题,特意从网上复制了一个udp socket的例子,进行发送接口不同的异常参数设置,发现udp socket的发送接口函数对于异常参数输入,虽然得到的errno的值是各不一样的,但就是不是为errno == 1的错误码!
积累了两天的观察和对比分析,以及基于过去对于k8s service IP是通过iptables进行NAT转换到达后端POD IP; 如果通过tcpdump抓取报文,就会发现访问service IP的报文,实际上被转换为POD IP投送过去,所以,k8s的很多网络问题,必须首先保证POD网络,或k8s节点网络的互通!
猜测在启动节点,k8s对于iptables nat规则设置可能处于中间态,在NAT规则未设置完全的情况下,对于某些service IP网络服务Endpoint进行访问,发送网络报文,就会在防火墙层面拒绝了,进而,socket接口返回错误码,出现无权限提示!
有了怀疑的方向和测试程序在手,就可以进一步验证是否如此!
通过防火墙命令设置测试程序的目的port被不允许,则在测试程序中,就打印了‘permission not allowed’的错误提示:)
知道的原因,就可以根据这个原因,采取一些规避的措施了!
一切都得到了解释,是如此的欢快!!!
- #include <stdio.h>
- #include <string.h>
- #include <errno.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
-
- int main(int argc, char * argv[]) {
-
- int client_sockfd;
- int len;
- char buf[BUFSIZ] = {}; //数据传送的缓冲区
-
- struct sockaddr_in remote_addr; //服务器端网络地址结构体
- remote_addr.sin_family = AF_INET; //设置为IP通信
- remote_addr.sin_addr.s_addr = inet_addr("172.16.6.1"); //服务器IP地址
- remote_addr.sin_port = htons(8000); //服务器端口号
-
- /*创建客户端套接字--IPv4协议,面向无连接通信,UDP协议*/
- if ((client_sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
- printf("\n create socket error");
- return 1;
- }
-
- strcpy(buf, "This is a test message"); // 发送的内容
- printf("sending: '%s'\n", buf);
-
- /*向服务器发送数据包;如果出现安全因素阻拦,例如,防火墙,则出现errno == 1 的错误码*/
-
- if ((len = sendto(client_sockfd, buf, strlen(buf), 0, (struct sockaddr * ) &remote_addr, sizeof(struct sockaddr))) < 0) {
- char szErrno[128];
- strerror_r(errno, szErrno, sizeof(szErrno));
- printf("\n sendto error, errno:%d, %s", errno, szErrno);
- return 1;
- }
-
- printf("\n close udp socket fd\n");
- /*关闭套接字*/
- close(client_sockfd);
-
- return 0;
- }