【问题标题】:Simple socket forwarding in linuxlinux中的简单套接字转发
【发布时间】:2018-07-06 14:17:34
【问题描述】:

场景很简单:

使用 TCP/IP 我有一个连接到我的客户端(服务器)我想将套接字发送给我的数据转发到我打开的另一个套接字,并将我从该套接字接收的数据向后转发。就像代理一样。

现在我有 1 个线程来监听传入的连接,并在建立来自客户端的连接时产生另外 2 个线程。我必须使用一种机制在线程中进行通信。

有什么更简单的东西可以用作 TCP/IP 代理吗? Linux 是否有套接字转发或某种机制?

【问题讨论】:

  • 为什么在传入连接上产生两个新线程?一个就足够了,它可以在两个连接之间进行发送和接收。阅读有关非阻塞套接字和select 系统调用的信息。
  • 更简单的东西到底是什么意思?套接字本身不会神奇地做任何事情,您需要手动编写代码来接收和转发流量。通常有几种可用的开源代理,例如 squid。但它们基本上是网络代理。不适用于任何 tcp 连接,而仅适用于 HTTP。

标签: c linux sockets


【解决方案1】:

你可以使用 iptables 来做port forwarding。这不是一个 c 解决方案,而是一个 2-line,它具有良好的性能并且调试最少。

来自第二个链接:

iptables -A PREROUTING -t nat -i eth1 -p tcp \
         --dport 80 -j DNAT --to 192.168.1.50:80

iptables -A INPUT -p tcp -m state --state NEW \
         --dport 80 -i eth1 -j ACCEPT

第一行从端口 80 转发到 192.168.1.50 上的端口 80,第二行接受连接,防止 iptables 丢弃它。

您可以使用其他 iptables 标志添加额外的约束,例如 -s 10.0.3.0/24 将捕获源为 10.0.3.0 到 10.0.3.255 的所有地址

【讨论】:

  • 谢谢,但我必须根据传入的 ips 路由流量
  • 你可以用额外的标志来做到这一点,比如 -s
【解决方案2】:

一种用户级解决方案是使用socat。例如,要接受端口 8080 上的连接并将它们转发到 192.168.1.50:9090,您可以使用:

socat TCP-LISTEN:8080,fork TCP:192.168.1.50:9090

fork 选项使socat 允许多个连接。

【讨论】:

  • 我必须根据传入的 ips 路由流量
  • 使用iptables 方法可以为源地址(--source)添加匹配规则。在用户空间中执行此操作需要更高级的东西,例如使用 squid 代理程序。
【解决方案3】:

您不需要线程。查看select()epoll()kqueue(),以便在没有任何线程的情况下管理多个套接字(如果您使用的是Windows,则为completion port)。

This is an example of a select-based server,这将是一个好的开始。

【讨论】:

    【解决方案4】:

    对于简单的套接字转发,让内核来做。使用 iptables 或其中一个前端来配置它。

    如果您需要复杂的数据嗅探/修改/转发以供实际使用,请编写一个 iptables 模块。

    如果您需要 tee(复制/拆分)数据流,或者检查或修改数据,请继续阅读。

    Linux 2.6.17 及更高版本以及 glibc 2.5 及更高版本确实提供了一些不错的功能:splice()tee()。您可以使用这些来避免将 payload 复制到用户空间和从用户空间复制,告诉内核将特定数量的字节从一个描述符传输到另一个描述符。 (tee() 不消耗数据,允许您将数据的一个或多个副本发送到其他描述符。)

    您可以在每个连接中使用两个线程(每个方向一个),并根据需要让每个线程读取检查/损坏/发球数据流。当您知道有 N 个传入字节要转发到一个传出套接字时,请使用 splice()。如果您有多个传出套接字,请使用非阻塞传出套接字,一次使用小块 tee()(但每个块的最后一个传出套接字使用 splice())。

    您的线程可以读取部分/全部传入数据以决定如何处理它,但请记住,在使用 @987654331 之前,您需要 write()send() 已读取需要发送的部分@或tee();他们不会神奇地获取已经消耗的数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-20
      • 2011-12-03
      • 2013-12-25
      • 1970-01-01
      • 1970-01-01
      • 2023-04-03
      相关资源
      最近更新 更多