Random Stuff from GlacJAY

[翻译] 用 Ruby 写编译器之零

这是一个国外的编译器达人写的一系列教程,内容为用 Ruby 语言,以自底向上的方式开发一个 Ruby 语言的编译器。这个教程非常适合于实战派的程序员。该教程的入口见这里,其代码见这里

我会试着翻译一下这个教程。由于这个项目之后又有了很大的进展,而教程本身却又已经很久没有更新了,所以之后我可能也会自己总结一下那些最新的开发工作。

总结一下学到的 LVS 相关知识( DR 模式)

不喜欢看长的 Blog 文章,当然更不喜欢写,所以就分开写啦。另,因为 TUN 模式限制更多,实际很可能用不到,所以不一定会写。

所以这次要讲的是 DR 模式的负载均衡啦。 DR 模式,也就是 Direct Route ,其基本原理就是不对包做任何处理,直接转给所分配的真实服务;回包则由真实服务直接发给客户端而不走负载机。因为不像 NAT 模式那样有相似的架构可以参考,所以这次就上图来说明啦(注,该图偷自这里)。

总结一下学到的 LVS 相关知识( NAT 模式)

LVS,即 Linux Virtual Server 的简称,是 Linux 下用来实现负载均衡的一个项目。它支持三种负载模式,分别为 NAT 、 DR 以及 TUN 。

注意,我这里讲的都是针对的 2.6 的内核, 2.4 、 2.2 、 2.0 版内核的实现方法和配置方法都各有不一样的地方。还好我不需要维护历史遗留系统(擦汗)。

首先是最简单的 NAT 模式。这种模式跟普通的 NAT 防火墙的原理差不多,只不过它会根据指定的分配策略,为每一个新的客户端连接选择一个不同的真实服务,而不是像 NAT 防火墙那样只映射到后台的同一个真实服务。

发布一个寻找局域网内主机的小工具

在工作中,经常需要远程登录到机房中的设备上进行调试与开发,走的是工作局域网。由于这些设备的地址也是动态获取的,因此在遇到一些意外事故,如网线松了、网络不稳定之类的,这些地址可能就变了。每当这时,我们就得跑到机房,给设备连上显示器(我们连 KVM 都没有,命苦啊),查看 IP ,然后再跑回去重新连。太麻烦了。

我知道有支持动态地址的 DNS 服务,可是我们没权限操作 DNS 服务器,而且设备也都是不固定的,没必要惊动网络管理员(好吧,我甚至都不知道谁是网络管理员,作为三年的“老”员工,我面壁去了。好吧,其实我就是想写写程序练练手),所以我就写了个小程序,用来查找一台特定设备的 IP 地址。

原理其实很简单啦。客户端(也就是我的笔记本)发个 UDP 广播报文,里面有要找的主机的名字。服务端呢,启动时则指定一个主机名字。当服务端收到一个 UDP 广播报文,并且发现找的就是自己呢,就返回一个 bingo 报文。这样,客户端就知道这个主机的 IP 地址啦。

Linux 下有关环境变量与换行符的一个小问题

最近在工作中,老是遇到一个莫名其妙的问题。我有一个用来设置一些环境变量的脚本,结果经常发现这个脚本设过的环境变量乱七八糟的,像 PATH 这种,就是之前的值跟后面添加的值重叠在了一起。直到后来才发现,原来是换行符搞的鬼。

这样说还不太清楚,上代码吧。编辑文本文件 test.sh 如下,记得以 DOS 换行符的模式来保存:

OpenVPN 的并发测试方法

由于 OpenVPN 本身协议的特殊性,用一般的方法不太好测它的并发。看过 LoadRunner ,但也最多只支持标准的 SSL/TLS 协议(当然,我也没细看这个)。于是动手改了其客户端的实现,最终完成任务。

其实阻止我们在一台机器上同时跑很多 OpenVPN 客户端的因素就只有虚拟网卡一个。貌似装十个左右的虚拟网卡驱动之后,机器就不行了。于是解决办法也很简单,把虚拟网卡相关的功能跳过就可以了。根据上篇的说明,只要在 incoming_push_message() 函数中,把对 do_up() 的调用直接换成 initialization_sequence_completed() 就 OK 了。

OpenVPN 的初始化过程分析

题外话:Eclipse CDT 很给力,至少在我用起来,比 gVim + Cscope 或者 SourceInsight 要来得给力,推荐一下。

更准确的来说,是 OpenVPN 的客户端与服务端之间,从协商密钥、到推送配置,以及最后的网卡与路由配置生效,开始进行 IP 报文的传递,这整个的过程。

完了。嗯,整个过程就像上面说的,这几个步骤而已。

不过重点当然还是代码啦。以前一直以为 OpenVPN 的点对点模式下,两端会进行一个决定谁是客户端,谁是服务端的协商过程,一直都想知道是怎么做的。后来才知道,原来通过配置信息,就已经决定好这个了。当然,我下面说的是客户端-服务器模式。

OpenVPN 的握手协议分析

又是好久没来这儿了啊。

最近因为工作需要(其实也没需要那么多),一直在断断续续地看 OpenVPN 的代码,终于大概搞清楚了它的握手是怎么个流程了。简单来说的话其实非常的简单,首先在 reliable 模块中实现了一个可靠的 UDP 报文协议,就是加上超时重传和确认报文的功能;然后用该协议交换一个 Hard Reset 命令,开始握手;最后建立 SSL 对象,并且通过内存 BIO 在可靠 UDP 协议的基础上转发 OpenSSL 的握手协议报文,通过这个 SSL 连接交换 OpenVPN 自己的密钥。接下来就是用这些密钥,该干嘛干嘛了。

用 Python 操作虚拟网卡

在我的 XTunnel 项目中,已经用 Python 作过这种相对底层的工作了(这说明 Python 果然还是非常强大的,上下层通吃啊),不过那边目前还是只实现了 Linux 的版本。后来我又陆陆续续地把 Windows 以及 Mac 下的操作方法给搞通了,今天就来总结一下。

在 Linux 内核中,特别是在现在的发行版中,应该都已经有了 TUN/TAP 虚拟网卡的驱动程序,看一下有没有 /dev/net/tun 这个文件就可以知道了。如果没有,就执行一下 sudo modprobe tun 这个命令吧。如果还是没有,那就 Google 之吧。下面上代码:

通过 ODBC 接口访问 Oracle 数据库 -- Linux 篇

首先,你要安装好 UnixODBC 软件包,这个就不多说了。

然后,安装 Oracle 官方客户端,因为我的使用环境为 Fedora 12 ,所以我下载安装的是 oracle-xe-client-10.2.0.1-1.0.i386.rpm

装好之后,要设置一些环境变量,我是用的一个 Shell 脚本来完成这项工作的,你可以把它放在 /etc/profile.d/ 目录下并加上可执行权限来让其在系统启动时自动执行,也可以直接运行这个脚本来使其立即生效。脚本如下: