部分OSX中,使用80端口的socket程序异常
开发OSX下socket client的时候遇到诡异问题,在多台mbp上测试,部分有问题,另外的正常,似乎和osx的版本无关。
简化版的代码如下,这就是一个最基本的socket client例子。
1 int main() {
2 int port = 80;
3 char *content = "hello world";
4 int fd = socket(AF_INET, SOCK_STREAM, 0);
5 struct sockaddr_in server;
6 server.sin_addr.s_addr = inet_addr("127.0.0.1");
7 server.sin_family = AF_INET;
8 server.sin_port = htons(port);
9 if (connect(fd, (struct sockaddr *)&server, sizeof(server)) == 0) {
10 printf("connect ok\n");
11 write(fd, content, strlen(content));
12 } else {
13 printf("connect fail\n");
14 }
15 return 0;
16}
在部分mbp上的问题如下:
- 当port为80或8080时,line 9的connect调用直接返回0,进入line 10输出connect ok。但实际上本地并没有80或8080端口的服务端应用。全程用tcpdump抓包,也看不到任何tcp包。
- 当port非80或8080时,line 9的connect失败,输出connect fail。且tcpdump抓包可以看到client发出syn包,server返回reset包,一切正常。
- 当port为80或8080时,如果content内容为包含"HTTP/"和"\r\n\r\n"的字符串,虽然依然错误的输出了"connect ok"。但随后在tcpdump中,可以看到client发出syn包,server返回reset包。
以上现象使用telent、nc做client端,或以非127.0.0.1的地址做服务端,均可重现,且确认没有开系统防火墙。
猜测是OSX中某个机制默认80和8080为http专用端口,于是拦截了系统调用,直到应用中发送了完整的一个http请求(http请求刚好以\r\n\r\n为结尾)才尝试真正的连接并发送数据。
google了很久,居然没有找到任何相似的问题。
有人遇到过这个问题么,类似机制如何disable掉呢?OSX下如何查看谁hook了系统调用呢?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
原因是cisco vpn软件的安全模块,执行
sudo /opt/cisco/anyconnect/bin/websecurity_uninstall.sh
即可记录一下解决的大神的思路。
1. 使用netstat确认本地没有打开80端口
2. 首先怀疑这是不是OSX的特性,比如有未知的socket选项。于是大神写程序,遍历设置了所有socket选项。发现都无法解决问题。
3. 进一步怀疑有firewall之类机制,查看当前进程和系统日志/var/log/system.log,发现问题对应的系统日志"local acwebsecagent[156]: Connection : HTTP/ NOT FOUND. CMode : 0 TMode : 0",进一步确认,发现这是cisco vpn软件所带的security模块,删了就可以,问题解决。
相关链接:
http://www.cisco.com/c/en/us/td/docs/security/vpn_client/anyconnect/anyconnect30/administration/guide/anyconnectadmin30/ac06websecurity.html#pgfId-1065063
http://www.bennadel.com/blog/2559-cisco-anyconnect-vpn-client-may-block-cors-ajax-options-requests.htm