【笔记】和各大AI大语言模型合作写项目—slirp.go

发布于:2025-08-19 ⋅ 阅读:(12) ⋅ 点赞:(0)

最近和各大AI大语言模型一起合作写了个小项目,让大家看看AI离取代人类还差多远。

开发大家都在一个共享环境下,连docker都不能运行,rootless也没有。不过好在linux环境,弄个proot能apt或者yum install自由,但是诸如podman这样的程序还是没法运行。一阵恼火,于是下载了linux kernel直接ARCH=um编译出user mode linux,我自己运行自己的内核总可以了吧。

喜滋滋编译完,好了,这个kernel没有网络。挖坟找找自己以前写的文章看看当时怎么配置user mode linux的,结果是要tun/tap设备,这个需要管理员先开一些权限,在rootless下可以用,但是这个权限没开啊…

于是开始到处找不用tun/tap的方法。发现了user mode linux的网络可以支持daemonslirp模式,这不是很好么。于是兴冲冲跑去github搜索一下,有些好些年前的项目,编译出来,怎么都不能运行?daemon模式有点复杂的,相当于需要从二层网络开始处理…而slirp是三层网络,只处理ip packet。

那我只要有个程序处理这些ip packet连上internet,我的user mode linux不就可以联网了么。于是喊上LLM,这还不简单。

首先登场的当然是写代码目前最强的Claude4,让它用c写一个简单的slirp程序,结果程序是能一次性编译通过,但是好像用user mode linux加载没什么反应。然后尝试了下gemini2.5pro,gpt4o,qwen3,都不能一次性编译通过了都…

这下遇到瓶颈了,很烦躁。继续手动搜索,突然找到了libslirp,眼前一亮。于是让claude4用c和libslirp写一个简单的slirp程序,程序有一处错误改正下就能正常编译了,但是运行以后还是什么都没有。于是手动从libslirp的gitlab上扒下来一个ping的example,发现编译不过,原来是libslirp最新已经4.9了,一般linux源里的都还是4.4,版本号改变不大但是内部api有一些大动静…加上文档写得很差,AI都写得不太对了。(所以知道了吧,要想不被AI取代,请把项目文档写差一点…目前为止我让AI写调用公司产品API的代码复杂的就没有对过的,发现它被文档毒害得不浅,或者说产品文档实在质量太差,连参数都能列错…而开发k8s operator代码刚刚的,因为人家文档不错,正确案例也多…)

写了半天,发现这个libslirp好像只是一个网络packet封装啊,看完文档发现它还是要靠一些手段诸如tun/tap连到外面…我要是能这么做,早就iptables配置好了啊…然后还试用了下slirp4netns(unshare -> no permission),同样的问题…

然后继续搜索引擎,突然找到了个pySLiRP,它是需要一个/dev/usbXXX设备作中介,通过PPP协议传输packet数据的。于是我又仔细看了下slirp的说明,据说是通过stdin和stdout交换数据。于是拿到这个pySLiRP以后,看了下它是通过打开usb设备设定baud rate通信的,我让AI写点代码把它替换掉不就好了?于是让claude4和gemini2.5pro比赛写代码,因为pySLiRP用的是asyncio,它通过第三方库打开usb设备得到async的readerwriter,这下目标明确,让俩模型写一段python代码将stdin和stdout转化为async的readerwriter。哔哔哔,代码写得很快,claude4响应比gemini快不少,质量也好很多,但是有些时候claude4没处理好的细节可能gemini可以补上一些,所以基本我还是喜欢让2个模型一起写代码,增加成功率(qwen3的代码能力确实还是有待提高的,大部分时候不能满足开发要求,所以这里暂时选了claude4+gemini2.5pro)。这次AI的代码直接放到原有代码里,把接口换成调用AI的代码,一次性成功。我还让AI给加了dump hex数据到stderr的代码。运行user mode linux,配置网络,ping一下某个ip,然后终于有数据打印到stderr了。

因为网络知识奇差无比,这些hex是啥意思?直接问AI好了,解释下这坨binary是什么意思。哦,很给力,两个AI都解析出了这坨binary是一个ip packet,并且是一个icmp ping的packet,只是两头多了0xc0。这里claude说不知道这是啥意思,但是gemini给出了猜测,根据这个0xc0,很像是slip的protocol。

然后再去查slip protocol,原来就是一些encode/decode的约定。这时候再读pySLiRP的代码,用了一套PPP protocol,牛头不对马嘴啊…但是有了最基础的输入输出数据样本,我又试了一下libslirp,完全不知道怎么控制它啊…算了,用raw的形式先把ping搞定,至少要先让ping有unreachable host输出。

于是先让AI写了俩函数去encode和decode slip,这样我们从stdin拿到数据,然后decode以后就是一个纯ip packet了。然后让AI写一个函数,如果我有一个ping的ip packet,解析之后生成一个unreachable host的ping response。对于这种特别明确的任务,claude4可怕的地方就来了,一次性写对,直接使用。于是我们有了第一个slirp的python版本——slirp.py。放到user mode linux里,配置好网络,ping一下,稳定得到unreachable host了!甚至其他curl或者网络请求都会得到“无响应”的响应。最初版本成功!

写到这里突然意识到目前这个项目实际上是写一个程序,这个程序要求是一边处理ip packet,另一边处理和外界的联系,有点像NAT,或者更像proxy,但是不同的地方是两边处理的粒度不一样。比如ping,我们得到ip packet,然后我们要把icmp的payload拿到,然后使用user mode下的socket发送这些payload,再得到response payload,并且构造ip packet去响应user mode linux的网络请求。

所以刚才的unreachable host版本写完以后,我让AI写一个程序,可以rootless得发送icmp payload,并且得到icmp response,并生成一个可用得response ip packet…把这次的代码和最初版本接起来,得到一个可以ping外部ip的slirp版本。当然,如果是ping内部同虚拟网段的机器,我们还可以让AI写个程序一直response ok就好了。至此ping的部分就做好了。

这给了我一部分和AI继续合作的信心。因为考虑到后续python的运行速度可能会比较慢,所以又让AI把之前的代码用golang写了一遍。很不错,各个部分都是一次性编译通过并且运行无误。

之后就进入udp处理的部分了。这个部分主要是先支持ping www.csdn.net,因为上面的最初版本,里面会判断如果是icmp ping,再判断是内部网络还是外部网络ip,就能走通ping,其他的ip packet还是unreachable host,所以ping www.csdn.net会告诉我domain name暂时不可用,打出的ip packet第一个也是一个dns query的udp packet。relay吧,udp packet发送过来,然后slirp维护一个map,并和对应net.UDPConn通信就好了。从udp packet里拿到payload,拿到服务器的ip和port,发送payload,拿到response,拼接一个合适的ip packet发送回去,通路成功!这下ping一个域名也可以了。我出要求,AI写代码,我负责integration整合并且debug…还算顺利。

之后有一个难题就是udp是无状态的,那我在map里的connection什么时候释放呢?之后想了个简单策略,如果30s没有通信,直接timeout释放掉,之后它发送数据再创建连接好了。至于udp server如何处理,暂时不慌,以后再说吧。

接下来就是处理tcp了。这个时候也是gpt5刚出来的时候,让它写了点代码,真的是牛头不对马嘴,算了,还是继续claude4+gemini吧…这个时候代码已经有个600多行了,在免费的高级模型里,已经不能读代码然后改了。没关系,我们直接让它写一个处理tcp的ip packet,然后再写一个程序处理tcp payload的读写,把两个程序代码拼一起就完成了最基本的。

这个时候把claude4的代码贴进去,运行,然后curl http://bing.com,看到log已经显示连接到bing的ip,并且发送了http request,只是curl一直报错 http/0.9 not allow之类,傻眼了。把代码片段贴给俩AI模型,然后告诉我了几个错误的bug…这下抓瞎了…只能看看curl的源代码哪里报这个错,但是看代码还是要花不少时间…

这个时候正好是gpt5出了gpt5-high和gpt5-chat不同版本的时候,那就试试gpt5-high吧,把处理tcp的部分直接贴给它,它直接指出了错误,给口碑崩塌的gpt5挽回了一些颜面…原来是处理SYN SYN-ACK ACK的时候SeqNum忘了加一!不错,AI对有效context内代码的理解已经很给力了。

写到这里,slirp.go已经在没有第三方库的情况下1000多行能够处理简单curl http://some-index-server了,比如准备好一个写了world的hello文件放nginx上,curl一下会返回world。之后接着就要考虑如何给超过MTU的tcp分片传输了…先休息下,等完成了放代码出来…

(未完待续)


网站公告

今日签到

点亮在社区的每一天
去签到