在 Haskell 中编写 tsocks 克隆有多合理/可能/困难

发布于 2024-10-16 04:41:40 字数 250 浏览 8 评论 0原文

我是一个相当有能力的程序员,了解 haskell,但没有在任何重大项目中使用过它。我对 C 和系统以及网络编程有足够的了解,我相信我可以从源代码中分离出 tsocks代码。

我对 haskell 提供的低级系统接口没有任何经验。我正在寻找人们可以就这个话题向我提供的任何建议,包括“不要这样做;你会因此讨厌自己”,前提是有一个解释。

I'm a reasonably competent programmer who knows haskell, but who hasn't used it in any major projects. I know enough about c and systems and network programming that I believe I can pick apart tsocks from the source code.

I don't have any experience with the low-level systems interfaces haskell provides. I'm looking for any advice people can offer me on the topic, including, "Don't do it; you'll hate yourself for it," provided there is an explanation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

汹涌人海 2024-10-23 04:41:40

我真的不会这样做,除非作为一个实验。我是一个 Haskell 人,但不是一个深入的系统人,所以有一个警告。但尽管如此,我在 tsocks 页面上看到以下内容:

tsocks是基于‘共享库’
拦截器的概念。通过使用
LD_PRELOAD 环境变量或
/etc/ld.so.preload 文件 tsocks 是
自动加载到进程中
每个执行程序的空间。从
在那里它会覆盖正常的
connect() 函数通过提供其
自己的。因此,当应用程序调用
connect() 建立 TCP
连接它而不是传递控制
到tsocks。 tsocks 确定是否
连接需要通过
SOCKS 服务器(通过检查
/etc/tsocks.conf)并协商
连接如果是的话(通过使用
真正的connect()函数)

可以从 C 调用 Haskell,反之亦然。事实上,这相对容易。对于共享库,请参阅:http: //www.haskell.org/ghc/docs/6.12.1/html/users_guide/using-shared-libs.html

但是,当您从 C 调用 Haskell 时,您需要 A) 在运行时中链接并 B) 调用运行时。

因此,当 C 知道它正在调用 Haskell 时,这就起作用了。但是,当 C不知道它正在调用 Haskell 时,这就相对比较棘手,因此您需要用一个 C 库来包装 Haskell 共享库,该库对程序透明地调用和管理运行时正在预加载 haskell-tsocks 库以拦截其正常的连接功能。

所以我确信这是可以完成的——但这听起来相当痛苦和复杂,而且就必须链接整个 ghc 运行时来实现这一功能而言有点昂贵。坦率地说,我想您要编写的代码(我还没有检查 tsocks 代码本身)无论如何都会主要是 FFI 调用。

因此,Socks 某些元素(代理、客户端等)的 Haskell 实现听起来很有趣并且可能有用。但 tsocks 所做的确切的预加载魔法听起来可能不太合适。

请记住,有些 Haskell 黑客在这方面比我做得更好,知识更丰富,经验也更丰富。所以他们可能会说另外的话。

I really wouldn't do this, except as an experiment. I'm a Haskell guy, but not a deep systems guy, so there's a caveat there. But nonetheless, I see the following on the tsocks page:

tsocks is based on the 'shared library
interceptor' concept. Through use of
the LD_PRELOAD environment variable or
the /etc/ld.so.preload file tsocks is
automatically loaded into the process
space of every executed program. From
there it overrides the normal
connect() function by providing its
own. Thus when an application calls
connect() to establish a TCP
connection it instead passes control
to tsocks. tsocks determines if the
connection needs to be made via a
SOCKS server (by checking
/etc/tsocks.conf) and negotiates the
connection if so (through use of the
real connect() function )

It is possible to call Haskell from C, and vice-versa. And its relatively easy, in fact. For shared libraries, see this: http://www.haskell.org/ghc/docs/6.12.1/html/users_guide/using-shared-libs.html.

But when you invoke Haskell from C, you need to A) link in the runtime and B) invoke the runtime.

So that works when the C knows that its calling Haskell. But its relatively trickier when the C doesn't know that it's calling Haskell, and so you'd need to wrap the Haskell shared library with a C library that invoked and managed the runtime transparently to the program that is preloading the haskell-tsocks library to intercept its normal connect functions.

So I'm sure this can be done -- but it sounds rather painful and complicated, and somewhat expensive in terms of having to link the whole ghc runtime in for this one feature. And frankly, I imagine the code you'd be writing (I haven't inspected the tsocks code itself yet) would largely be FFI calls anyway.

So a Haskell implementation of some element of socks -- a proxy, a client, etc. sounds interesting and potentially useful. But the exact preload magic that tsocks does sounds like a perhaps poor fit.

Bear in mind that there are Haskell hackers that are much better at this stuff than me, more knowledgeable, and more experienced. So they might say otherwise.

紧拥背影 2024-10-23 04:41:40

(作为单独的答案发布,因为这是与 FFI 无关的建议)

您可能知道这些东西,但万一它对任何人都有用......

  • 请阅读 Network.Socket 模块
  • 在 Haskell Wiki 中搜索可能对您有帮助的页面(例如 应用程序和库/网络
  • 查看Haskell 中的系统编程 以及 RWH 的其他章节
  • 忽略那些说“Haskell 对于 I/O 来说很糟糕”的人 - 专业提示:你可以吓唬他们说一些花哨的词,比如“endofunctor”

(Posting as a separate answer, since this is advice unrelated to the FFI)

You probably know this stuff, but in case its useful for anyone...

橘香 2024-10-23 04:41:40

这可能不完全是您正在寻找的答案,但您可以使用 外部函数接口将现有的 C 实现包装在 Haskell 类型中。

请注意,Haskell 2010 中的几个主要变化之一是正式将 FFI 作为一项语言功能包含在内。链接:Haskell 2010 FFI

This may not be exactly the answer you were looking for, but instead of re-writing it in Haskell, you could just use the Foreign Function Interface to wrap the already-existing C implementation in Haskell types.

Note, one of the few major changes in Haskell 2010 was to officially include the FFI as a language feature. Link: Haskell 2010 FFI

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文