【问题标题】:What is the need for "maxfd" when creating a tunnel?创建隧道时需要“maxfd”吗?
【发布时间】:2019-05-03 18:25:39
【问题描述】:

在此链接https://backreference.org/2010/03/26/tuntap-interface-tutorial/ 中,有一个使用 tun/tap 接口创建 TCP 隧道的代码示例,如下所示。

  /* net_fd is the network file descriptor (to the peer), tap_fd is the
     descriptor connected to the tun/tap interface */

  /* use select() to handle two descriptors at once */
  maxfd = (tap_fd > net_fd)?tap_fd:net_fd;

  while(1) {
    int ret;
    fd_set rd_set;

    FD_ZERO(&rd_set);
    FD_SET(tap_fd, &rd_set); FD_SET(net_fd, &rd_set);

    ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);

    if (ret < 0 && errno == EINTR) {
      continue;
    }

    if (ret < 0) {
      perror("select()");
      exit(1);
    }

    if(FD_ISSET(tap_fd, &rd_set)) {
      /* data from tun/tap: just read it and write it to the network */

      nread = cread(tap_fd, buffer, BUFSIZE);

      /* write length + packet */
      plength = htons(nread);
      nwrite = cwrite(net_fd, (char *)&plength, sizeof(plength));
      nwrite = cwrite(net_fd, buffer, nread);
    }

    if(FD_ISSET(net_fd, &rd_set)) {
      /* data from the network: read it, and write it to the tun/tap interface.
       * We need to read the length first, and then the packet */

      /* Read length */
      nread = read_n(net_fd, (char *)&plength, sizeof(plength));

      /* read packet */
      nread = read_n(net_fd, buffer, ntohs(plength));

      /* now buffer[] contains a full packet or frame, write it into the tun/tap interface */
      nwrite = cwrite(tap_fd, buffer, nread);
    }
  }

该代码摘录中“maxfd”的目的是什么?确切的行是:

maxfd = (tap_fd > net_fd)?tap_fd:net_fd;

ret = select(maxfd + 1, &rd_set, NULL, NULL, NULL);

【问题讨论】:

  • 如果你做了printf("%ld\n",sizeof(fd_set));,你会看到字节数合二为一。乘以 8。你会得到大约 1,000 左右。 maxfd 告诉 select 只扫描到那个 [多] 更短的限制。这是一个效率问题。
  • 查看documentation for select,特别是nfds参数的描述。

标签: c tcp network-programming tcp-ip tunnel


【解决方案1】:

它是危险且过时的select 函数工作方式的产物。它需要一个参数,该参数是传递给它的fd_set 对象的大小(以位为单位),并且不能使用大于FD_SETSIZE 施加的任意限制的fd 数。如果您未能满足这些要求,则会导致未定义行为。

无论您在哪里看到select,都应将其替换为poll,它不受这些限制、界面更易于使用且功能更多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 2012-03-28
    • 2018-02-14
    相关资源
    最近更新 更多