• 防火墙导致Linux发送网络报文出现errno等于1的错误码


        服务启动过程中,偶然间看到udp socket发送报文,出现 errno == 1 错误码。

        错误码对应的描述:

    1.    zh_CN: 不允许的操作
    2.    en_US: Operation not permitted

      出现错误的代码,在失败后,下次定时尝试重作,无权限问题不出现了,具有偶发性!

    分析


       在服务器启动过程中发送网络报文,出现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’的错误提示:)

     知道的原因,就可以根据这个原因,采取一些规避的措施了!

      一切都得到了解释,是如此的欢快!!!

    Linux UDP Socket 编程例子


    1. #include <stdio.h>
    2. #include <string.h>
    3. #include <errno.h>
    4. #include <unistd.h>
    5. #include <sys/types.h>
    6. #include <sys/socket.h>
    7. #include <netinet/in.h>
    8. #include <arpa/inet.h>
    9. int main(int argc, char * argv[]) {
    10. int client_sockfd;
    11. int len;
    12. char buf[BUFSIZ] = {}; //数据传送的缓冲区
    13. struct sockaddr_in remote_addr; //服务器端网络地址结构体
    14. remote_addr.sin_family = AF_INET; //设置为IP通信
    15. remote_addr.sin_addr.s_addr = inet_addr("172.16.6.1"); //服务器IP地址
    16. remote_addr.sin_port = htons(8000); //服务器端口号
    17. /*创建客户端套接字--IPv4协议,面向无连接通信,UDP协议*/
    18. if ((client_sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
    19. printf("\n create socket error");
    20. return 1;
    21. }
    22. strcpy(buf, "This is a test message"); // 发送的内容
    23. printf("sending: '%s'\n", buf);
    24. /*向服务器发送数据包;如果出现安全因素阻拦,例如,防火墙,则出现errno == 1 的错误码*/
    25. if ((len = sendto(client_sockfd, buf, strlen(buf), 0, (struct sockaddr * ) &remote_addr, sizeof(struct sockaddr))) < 0) {
    26. char szErrno[128];
    27. strerror_r(errno, szErrno, sizeof(szErrno));
    28. printf("\n sendto error, errno:%d, %s", errno, szErrno);
    29. return 1;
    30. }
    31. printf("\n close udp socket fd\n");
    32. /*关闭套接字*/
    33. close(client_sockfd);
    34. return 0;
    35. }

  • 相关阅读:
    Node.js之TCP(net)
    数据结构--单链表操作
    适用于90%网剧、网大的最新备案流程解析
    YOLOv5、YOLOv8改进:Swin Transformer-V2
    MATLAB环境下使用相关图可视化相关矩阵
    【文件输入输出流】Inputstream和Outputstream
    Cadence IC618使用
    随想:卖包子送了杯豆浆
    CentOS 7 虚拟机安装
    Wireshark过滤器的使用
  • 原文地址:https://blog.csdn.net/jkler_doyourself/article/details/125609720