linux环境中getnameinfo的问题

linux环境中getnameinfo的问题

在linux环境下获取本地IP地址的方法,通常都是先getifaddrs获取当前计算机中所有的接口信息,然后循环调用getnameinfo获取各接口的IP地址。

这是网络上常见的描述方式。在IPv4组网时,没有任何问题。但是在IPv6组网(获取IPv6地址)时,出现了问题。由该函数返回的IP地址字符串中包含了当前接口的名称,例如以下返回值:

fe80::5a94:6bff:fe48:4cec%wlan1

如果想获得纯粹的IPv6地址,应当通过接口地址信息,调用inet_ntop来转换IP地址为字符串,如下处理:

char ipstr[512]={0};
sockaddr_in6* sockaddr_ipv6=reinterpret_cast<sockaddr_in6*>(ifa->ifa_addr);
inet_ntop(AF_INET6,&sockaddr_ipv6->sin6_addr,ipstr,sizeof(ipstr));

此时获取的IP地址字符串信息就不再包含当前接口的名称:

fe80::5a94:6bff:fe48:4cec

IPv6地址带接口名称实际是“zone identifier (区域标识)”,在RFC6874规范中有相应的定义。

2014-06-08 updated:

在Linux系统中,要使用ping6命令来ping IPv6的地址,并且要求带上接口索引。例如如果只是ping IPv6地址,会返回以下错误:

ping6 fe80::a00:27ff:fe37:a9d0
connect: Invalid argument

正确的使用方法如下所示:

ping6 fe80::a00:27ff:fe37:a9d0%eth0
qt network中的一点问题

qt network中的一点问题

在一个小应用中使用了qt的network模块,调用网站的一个接口(HTTP GET方式),获得相应的结果。操作非常简单,可是却出现了问题。

首先是在windows上,运行程序后,提示无法定位libeay32.dll。这个是openSSL的动态链接库,不明白为什么qt4.8.5(windows)默认链接了这个库。查看文档,貌似缺省情况下是不编译进SSL功能的,而且我们用的包并不是自己编译的,是直接从qt网站下载安装的。解决方法也简单,无非就是安装openssl的库,copy相应的dll到exe文件同一目录下即可。

接着又出现了问题,调用HTTP后,服务器返回“406 NOT acceptable”。直接将链接放在浏览器中执行又没有任何问题。检查server上的log,发现apache启动了ModSecurity模块,该模块检查了User-Agent头,如果太简单则认为是假请求(spam请求?),拒绝该HTTP请求。

用wireshark抓了一下包,发现QNetworkRequest默认的User-Agent的确非常简单:

User-Agent: Mozilla/5.0

解决方式同样简单,我们强行修改为稍微复杂一点即可,例如:

QNetworkRequest netReq;
netReq.setUrl(destUrl);
netReq.setRawHeader("User-Agent","Mozilla/5.0 (X11; Linux x86_64)");

这样就可以绕开apache模块的检查。

简单判断当前linux的发行版本

简单判断当前linux的发行版本

初步用了一下最新发布的Ubuntu 14.04版本,大体上来说还是很不错。不过Unity7还是一如既往的奇葩,在与Qt程序的配合中更是如此。很不幸,我们的软件就是采用Qt,因此在Unity中有些莫名奇妙的小冲突,例如systemTray等问题,虽然不影响使用,但是给人的感觉很不爽、很不专业。

简单的处理方式就是程序自动判断当前是不是Ubuntu版本,然后再针对性地做一些处理就好了。目前还没有统一的API可以说明当前linux的发行版本信息,网上有各种各样的方式进行判断。对deb系的发行版本而言,以下方式经验证还比较靠谱:

直接读取/etc/issue文件,这个文件的内容目前包含发行版本信息。

这种方式有一些不确定之处:

(1)首先这个文件名就很奇葩。’issue’为什么是用来存储版本信息的? 为什么不直接用version或者别的更好、更直接的文件名?linux开发人员的思维总是让人搞不懂啊。

(2)既然没有人解释为什么会使用这个文件,同样也就没有人保证以后还会这么做。

丑陋的闾丘露薇

丑陋的闾丘露薇

事件来自于闾丘露薇转发和评论的一条视频:小孩当街大小便,大陆夫妻与港人激烈冲突。在这个事件中,身为新闻工作者的闾丘露薇完全缺乏职业素养,后续访谈和评论中,简单地以“不了解舆情”做借口更让人无法接受。

根据视频的内容,大陆夫妻是在厕所人多排队排不上、小孩憋不住的情况下,才在公共场合不得已而为之。而且小孩妈妈很显然用尿不湿等物品托着,并装进了自己带的纸袋中。闾丘露薇后来的说辞“找个角落避避”貌似很有道理,但是回避了一个简单的事实:那是在旺角!好吗!请您在节假日的旺角那几条街找个没人的角落出来!

其他评论更是罔顾事实:例如女子打人耳光、抢夺相机等。孩子妈妈阻止港人抢夺婴儿车,怎么就被指责为打人了?从视频中也很明显可以看到,是港人故意拖拽婴儿车,肆无忌惮地给人拍照(甚至拍私处!!)!

随手转发视频很容易,但是作为职业新闻工作者,难道没有看完视频才做判断?难道不应该了解一些基本情况再做评论?评论的时候难道不应该站在客观的立场?

事后的一些访谈和博文,更显得强词夺理、回避事实,完全无视客观、公正。自以为代表正义,却忽视了尊重事实这个基本的道理。大陆的确有很多让人看不起的地方,但这不等于就可以随便践踏事实。

整件事、整个人只能用一个词形容:丑陋!闾丘露薇应该停止争辩,并立刻道歉。犯错不可耻,可耻的是强词夺理!

2014-04-29 updated:

在网上看到据传是陈道明先生的评论,感觉很钦佩。对比闾丘露薇,真是美丑立现:

文明的意义除了不当街便溺,还有善意与宽容,前者是表象,后者才是根本。真正的文明,是碰到这样的情况,走过去善意咨询那位母亲是否需要帮忙,或者指引她找到厕所,而不是冷漠地拍照当成渲染大陆人素质低下的又一个证据。大陆人的素质的确有待提高,但香港人的文明同样需要提升。

2016-06-19 updated:

一位外国人评论:

It has been my understanding that Hong Kong people have always had an animosity towards mainland Chinese. There have been numerous times when Chinese people were looked down upon. I remember reading an article of a little girl who could not hold her bladder so, her mom got out a diaper and let her urinate on it. During this incident, there were some Hong Kong people who were taking videos of this incident causing a lot of trouble saying how uncivilized mainland Chinese people were. I’m American and all I know is this. If some pedophile tried to take a video of my 5 year old daughter urinating, I’d give them a serious beat down.

virtualbox与ubuntu14.04

virtualbox与ubuntu14.04

Ubuntu14.04版本今天正式发布并可下载了。从阿里云镜像网站下载了相应的iso文件,并在vbox中安装运行,感觉还是很不错,很显然ubuntu一直在进步。虽然在vbox中运行还是很慢,不过印象中比12.04要快一些,基本还是可以用的。

不过这个版本有个奇怪的问题(也许以前版本也有),在vbox中的解析度非常小,大概只有800*600。需要重新安装vbox附加工具才行:

sudo apt-get install virtualbox-guest-dkms

安装完后重启即可。

修正dropbox无法启动问题

修正dropbox无法启动问题

也许是Ubuntu系统升级补丁的原因,也许是dropbox升级遇到网络异常的原因,总之,今天忽然发现dropbox没有启动,在面板中看不到dropbox的小图标。

使用命令检查dropbox状态,的确没有启动:

dropbox status

手工强制启动dropbox:

dropbox start

提示以下错误:

VerificationError: ... : No module named _cffi__xa0c4f46bx1d95b4de

在网上搜到一个解决方案,其实就是重新安装dropbox。在此之前要先删掉.dropbox-dist目录。与网上文章不同的是,我是在用户目录下找到这个目录。

rm -fr .dropbox-dist/

删除完成后,重装dropbox即可。重装不会影响原有的同步目录。

dropbox start -i

备注:系统版本为 Kubuntu 13.10(x86_32); dropbox版本为2.6.27。

qt编译中抑制特定告警信息

qt编译中抑制特定告警信息

在编译某些代码时,我们希望抑制掉一些VC的编译告警,例如C4244(丢失精度告警)。我们可以直接修改mkspecs目录下对应的配置文件,但这样做会影响到所有工程,而我们实际上只希望对某些特定的工程关闭该告警。

可以直接修改pro文件,加入以下内容即可:

QMAKE_CFLAGS += /wd4244

如果是cpp文件,则指定以下参数即可:

QMAKE_CXXFLAGS += /wd4244
嘻嘻TV又被打脸了

嘻嘻TV又被打脸了

新闻“盗版用户无权指责微软不负责任”,原文链接如下:

http://www.cnbeta.com/articles/281535.htm

最后一句是亮点:

央视报道者对于安装方便的Ghost系统本身已属于盗版的概念居然毫无察觉。以盗版使用者的身份,去指控微软不对他们负责,脸皮也未免太厚。
php闭合标签害死人

php闭合标签害死人

今天调试一段很简单的php代码:无非就是echo一个字符串给javascript程序,由js程序根据字符串走不同的逻辑即可。

遇到一个问题,几乎被折磨死:js得到的字符串前面总是多了一个’\n’! 排查了apache、js、php等方方面面的问题,最后居然发现是闭合标签’?>’导致的。

在php的文档中清楚地写明:解析器实际上是不解析这个闭合标签’?>’的。但是如果使用了这个标签,则后面的空格、换行等字符都会被带入后面的引用,引起多余的输出等。

在我的遭遇中,当前php引用了另外一个php文件,那个php文件在’?>’后多了一个’\n’,这个多余的换行符就被带入到当前的php中了。

解决方法也很简单,php文件都不包含闭合标签即可。话说回来了,“闭合”的意思不就是关闭了、结束了么?php解析器的处理方式真是让人感觉莫名其妙啊。

iptables常用命令

iptables常用命令

前段时间安装fail2ban后,陆续发现了一批IP地址在尝试暴力破解我们服务器的用户名和密码。无论这些IP地址是来自可怜的肉鸡,还是真实的弱智黑客,直接屏蔽掉这些地址更好,免得浪费计算资源。

由于fail2ban实际也是利用了iptables,因此花了点时间研究iptables,干脆直接使用iptables屏蔽那些已经暴露的IP地址。以下是一些常用的命令:

查看iptables已有的规则

sudo iptables -L -n --line-numbers

删除一个已有的规则

sudo iptables -D INPUT 8

其中,’8’是INPUT链里的序号。

屏蔽一个IP地址,例如116.10.191.185

sudo iptables -A INPUT -s 116.10.191.185 -j DROP

屏蔽一段IP地址,例如从116.10.191.0 ~ 116.10.191.255

sudo iptables -A INPUT -s 116.10.191.0/24 -j DROP

注意,‘24’是mask位,表示采用头三个字节(24位)进行mask。

我们可以将上述规则写入/etc/rc.local,系统启动时能自动屏蔽这些垃圾IP地址。