有关壮壮和毛毛的日记

2011213

毛毛的梦

今天是住进306医院的第五天了。毛毛下午做了一个梦,是关于壮壮的。

广场上举行射雕英雄大赛,这时候有一个男青年戴着眼镜,被一个吊车到半空中,准备射大雕。还没射他就大叫“好恐怖哦……我受不了啦,我要下去……“。人群中爆发出一阵阵的嘲笑声:”现在的年轻人不行啦“。这时,突然一只大雕被射落到广场上。”咦,吊车上的人还没发箭,大雕怎么就掉下来啦?“。工作人员上去一检查,发现大雕是被弹弓射下来的。这时候,大家看到人群中一个拿着弹弓的小男孩。哈,原来是壮壮!”原来是壮壮用弹弓把大雕射下来啦!“——族长惊呼。梦境中的壮壮只有六七岁的样子,很小很帅的。族长继续说:”我们的射雕英雄终于后继有人啦!“。

毛毛睡醒后,躺在床上,忍不住笑得肚子痛。

——

关于喂奶

到今天,壮壮已经在NICU呆了五天。妈妈只有在壮壮出生的时候见过壮壮,之后就跟壮壮分开了。妈妈这几天很想壮壮,做梦的时候总是梦到。前天(11号)上午,壮壮撤掉了呼吸机。借着检查的机会,壮壮爸爸双手抱着壮壮去做了脑部CT。结果出来,没有问题,消息传遍全家,几天来的郁闷气氛一扫而光。壮壮爸爸终于见到了可爱的壮壮,双手抱着,壮壮爸爸激动不已。壮壮真的很漂亮,头发黑黑,耳朵大大,脖子像妈妈,好长——壮壮比照片上的好看多啦。

今天到晚上七点前,一共给壮壮送了三次眯眯。第一次是早晨8点钟。送去的时候护士刚好说壮壮饿了,就直接给壮壮喂了。这是壮壮吃到的最新鲜的一次——这次大约20毫升。第二次是十点钟左右,这次也是20毫升。之后壮壮妈妈又挤了三次奶,第三次壮壮妈妈实在很累,没挤出多少眯眯。第三次大约存了40多毫升,于四点左右送到NICU

2011214

毛毛的梦——Good morning

卢筱溪和毛毛睡在高低床上,毛毛睡上边,小溪溪睡下边。小溪溪睡醒了,对毛毛说:“good morning!”,毛毛回道:“Good morning!”

2011311

今天是壮壮第一次出家门晒太阳。哈哈!

一道纯正的Google式的“面试”题 – 其实每件事都可以做得更好

有一道Google的“面试”题,很简单,也很不简单。

题目:单链表,找到倒数第十个元素

1. 通常的做法是这样的,如下图所示:

便利一次链表,顺便保存一个指针跟在屁股后面第十个位置,当遍历完成时,屁股正好在第十个座位上。

2. 这时,Google的工程师会问:能不能做得更好,指针操作次数能否减少?

好说,很简单啊,遍历时建个索引就可以啦:

只需要遍历一次,以后找任何元素就是个哈希问题啦。

3. 这时又有问题了,索引占空间太大,能不能解决点空间呢?想想,这其实也不难,索引建小一点,使用带冲突的哈希表就可以,如下图所示:

一件小事,给我很深刻的启发:只要用心去想,其实每件事都可以做得更好,更完美。

谢谢你,Google。

Linux系统下桥接方式部署squid透明代理

今天小小研究了一下代理服务器原理以及Linux系统下桥接方式部署squid透明代理。 首先是部署方式,如下图所示: 上图中“透明代理”为Linux服务器。服务器有两快网卡,两块网卡以桥接方式部署到网络。服务器上安装有Squid服务以及Squid日志分析工具SRG。 Linux系统配置如下:

squid配置:

http_port 3128 transparent

http_access allow all

系统配置:

brctl addbr br0
brctl addif br0 eth0
brctl addif br0 eth1
ifconfig eth0 0.0.0.0 promisc
ifconfig eth1 0.0.0.0 promisc
ifconfig br0 up
dhclient br0
echo 1 > /proc/sys/net/ipv4/ip_forward
ebtables -t broute -A BROUTING -p ipv4 –ip-protocol 6 –ip-destination-port 80 -j redirect –redirect-target ACCEPT
/sbin/iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j REDIRECT –to-ports 3128
/sbin/iptables -t nat -A PREROUTING -i eth1 -p tcp –dport 80 -j REDIRECT –to-ports 3128
/sbin/iptables -t nat -A PREROUTING -i br0 -p tcp –dport 80 -j REDIRECT –to-ports 3128

具体数据流解释如下:

评万网的虚拟机业务

前段时间租用虚拟机,有幸对VPS hosting这个市场做了一个简单的调查。主要Focus在国外的VPS hosting市场,国内主要看了万网前段时间推出的基于云的虚拟机服务。让我们看看的是万网虚拟机服务。

整理了一下万网2011年2月26日的公开价格目录,如下:

Cores MEM Disk Bandwidth 价格(1年租约)
翔云I型 2 1.5G 150G 1000M共享 2M上限 5800
翔云II型 2 2.5G 250G 1000M共享 2M上限 7800
翔云III型 4 4G 500G 1000M共享 2M上限 11800
翔云IV型 4 8G 750G 1000M共享 2M上限 16500
翔云V型 8 16G 750G 1000M共享 2M上限 25500

VPS hosting现在主流的技术主要有几种:Xen,OpenVZ,以及VMWare等。其中以Xen,OpenVZ两种技术最为普遍,也有一些运营商采用VMware技术,但是不如主流。Xen技术使用半虚拟化技术,技术比较成熟,性能稳定可靠,几乎所有的VPS供应商都会提供基于Xen的虚拟化服务。

从公开信息看,万网的虚拟机技术使用的应该是Xen技术。从万网虚拟机的配置来看,万网虚拟机配置相对来说数据中高端配置,主要面向的用户应该是中小企业,甚至是大型企业用户。CPU核数从2个到8个;内存从1.5G起步,最高可以买到16G的容量;硬盘容量也不算小。

问题是,万网虚拟机无论配置如何,网络带宽仅仅有2M的容量,还是上限。这一点就把产品定位给弄残废了。万网的客户用虚拟机主要是办网站,而网站需要的主机配置和网站的负载是有关联的。这个道理很简单,相同的应用,浏览网页的人越多,需要的主机性能就得越好。相应的,网站流量也就越大。万网的带宽限制一下子就让所有的高配产品成了摆设。

纵向分析之后是横向比较。

来看看国外VPS厂商的情况:

首先是PhotonVPS

PhotoVPS同时提供Xen和VirtualVZ的虚拟机,我选择了与万网配置比较接近的几款Xen配置:

PhotonVPS
Plans Cores MEM SWAP DISK Traffic Up Time SLA Price (1 Year) Price in RMB
WRAP1 8 512MB 1GB 35GB 1000GB 99.90% 16.95×12 1340
WRAP2 8 1GB 2GB 50GB 1800GB 99.90% 26.95×12 2130
WRAP3 8 2GB 4GB 95GB 3000GB 99.90% 41.95×12 3320
WRAP4 8 4GB 8GB 165GB 5000GB 99.90% 82.95×12 6560

然后是Linnode。Linnode也是一个Xen VPS供应商:

Linnode
Plan MEM DISK TRANSFER Price(1 year) Price in RMB
Linnode 1536 1536MB 48GB 600GB 59.95×12 4750
Linnode 2048 2048MB 64GB 800GB 76.95×12 6090
Linnode 4096 4096MB 128GB 1600GB 159.95×12 12670

还有buyVM, ramhost等比较知名的VPS供应商,我就不一一列举了。相比国外的VPS来说,万网的产品除了数据中心在国内之外,真的没有什么竞争力。

所以给万网的几点建议:

1. 推出低端配置虚拟主机。

2. 网络带宽差异化定价。

3. 选择更适合虚拟化的运营的服务器,选择更便宜的数据中心技术,严格控制PUE,降低成本。

4. 用户不关心是不是云,用户只关心体验和成本。所以要找一个好的虚拟机技术架构师,还要找一个好的产品经理。

python小玩具:生成自动切换的桌面背景 for debian squeeze

#!/usr/bin/python

#Copyright William LI null@live.cn


import os
import shutil
import re
import sys
from collections import deque


WALLPAPER_INSTALL_PATH = "/usr/share/backgrounds/hubble"

WALLPAPER_CONFIG_FILE = ""

GNOME_WALLPAPER_CONFIG = "/usr/share/gnome-background-properties/hubble.xml"


def install_wallpaper_files(image_file_list):
	if not os.path.exists(WALLPAPER_INSTALL_PATH):
		print WALLPAPER_INSTALL_PATH + " doesnot exist, creating new one."
		os.mkdir(WALLPAPER_INSTALL_PATH)
	
	if not os.path.isdir(WALLPAPER_INSTALL_PATH):
		print WALLPAPER_INSTALL_PATH + "is not a directory."
		exit(0)

	# install the image files
	for src_image_file in image_file_list:
		image_file = os.path.basename(src_image_file)
		dst_image_file = os.path.join(WALLPAPER_INSTALL_PATH, image_file)
		shutil.copyfile(src_image_file, dst_image_file)


def static_config(fhandle, image_file):
	fhandle.write("""
	<static>
		<duration>60.0</duration>
		<file>""" + image_file + """</file>
	</static>""")

def transition_config(fhandle, from_file, to_file):
	fhandle.write("""
	<transition>
		<duration>5.0</duration>
		<from>""" + from_file + """</from>
		<to>""" + to_file + """</to>
	</transition>""")


def generate_wallpaper_config(image_file_list):
	config_file = open (GNOME_WALLPAPER_CONFIG, "w")
	config_file.write("""
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd"> 
<wallpapers> 
  <wallpaper deleted="false"> 
     
    <name>Hubble</name> 
    <filename>/usr/share/backgrounds/hubble/background-hubble.xml</filename> 
    <options>scale</options> 
  </wallpaper> 
</wallpapers>
	""")

	config_file.close()

	WALLPAPER_CONFIG_FILE = os.path.join(WALLPAPER_INSTALL_PATH, "background-hubble.xml")
	config_file = open (WALLPAPER_CONFIG_FILE, "w")	
	config_file.write("""
<background>
	<starttime>
		<year>2011</year>
		<month>01</month>
		<day>01</day>
		<hour>00</hour>
		<minute>00</minute>
		<second>00</second>
	</starttime>
	<!-- This animation starts 2011 new year midnight. -->""")

	image_file_queue = deque(image_file_list)	
	image_file = image_file_queue.popleft()
	from_file = os.path.basename(image_file)
	first_file = from_file = os.path.join(WALLPAPER_INSTALL_PATH, from_file)
	image_file_queue.append(image_file)
	
	while len(image_file_queue) > 0:

		static_config(config_file, from_file)

		image_file = image_file_queue.popleft()
		to_file = os.path.basename(image_file)
		to_file = os.path.join(WALLPAPER_INSTALL_PATH, to_file)
		
		transition_config(config_file, from_file, to_file)
	
		from_file = to_file	

	config_file.write("""
</background>""")
	config_file.close()


def main():
	if (len(sys.argv) < 2) :
		print "Help : " + sys.argv[0] + " IMAGE_DIR "
		exit(0)

	image_dir = sys.argv[1]

	if (not os.path.exists(image_dir)):
		print image_dir + " doesnot exist."
		exit(0)

	if (not os.path.isdir(image_dir)):
		print image_dir + " is not a directory."
		exit(0)

	image_file_list = []

	for root, dirs, files in os.walk(image_dir) :
		print root, "contains : "
		for filename in files : 
			print "\t" + os.path.join(root, filename)
			image_file_list.append(os.path.join(root, filename))

	#print image_file_list

	print "Installing wallpaper files:"
	install_wallpaper_files(image_file_list)
	print "done."

	print "Preparing wallpaper config file:"
	generate_wallpaper_config(image_file_list)
	print "done."



	
if __name__ == '__main__':
	main()



python小玩具:自动下载哈勃望远镜照片壁纸

#!/usr/bin/python
# William Li  null@live.cn

import os
import urllib
import urllib2
import re
from threading import Thread
from Queue import Queue

work_queue = Queue()

THREAD_NUM = 5

def download_worker():
	while True:
		url_line = work_queue.get()
		work_queue.task_done()
		if cmp(url_line, "stop_working") == 0 :
			print "Job done."
			break
		response = urllib2.urlopen(url_line)
		html = response.read()
		url_pattern = re.compile("http://imgsrc.hubblesite.org/hu/db/images/(?P<img_file_name>.+_wallpaper.jpg)")
		match = url_pattern.search(html)
		if match:
			img_download_url=html[match.start():match.end()]
			img_file_name = match.group('img_file_name')
			download_item = {"url":img_download_url, "file_name":img_file_name}

			if os.path.isfile(download_item["file_name"]):
				print "File already downloaded."
			else:
				print "Downloading " + download_item["file_name"] + " from " + download_item["url"]
				urllib.urlretrieve(download_item["url"], download_item["file_name"])
		

def main():
	print "start."
	hubble_gallery_url = "http://hubblesite.org/gallery/wallpaper"
	response = urllib2.urlopen(hubble_gallery_url);
	html = response.read()

	url_pattern = re.compile("/gallery/wallpaper/pr\w+/")

	url_list = url_pattern.findall(html);

	#print url_list

	img_url_list = []
	for url_line in url_list:
		#url_line = url_line.replace("album","album/entire")
		#url_line = url_line.replace("npp","warn/npp")
		url_line = "http://hubblesite.org" + url_line + "2048x1280_wallpaper/"
		img_url_list.append(url_line)

	print img_url_list

	threads = []
	for i in range(THREAD_NUM):
		t = Thread(target = download_worker)
		t.start()
		threads.append(t)
	
	for url_line in img_url_list:
		print "Opening " + url_line
		work_queue.put(url_line)
		
	for i in range(THREAD_NUM):
		work_queue.put("stop_working")

	for t in threads:
		t.join()

	print "waiting all jobs to be done."
	work_queue.join()
	print "All done."

if __name__  == "__main__":
	main()

华为HG527-C无线adsl路由器(北京联通定制)功能破解

华为HG527-C无线adsl路由器是华为公司为北京联通定制的一款无线家庭网关。可能是为了防止小区用户共享无线路由器,路由器上做了软硬件的限制。软件上限制了PPPoE拨号功能和路由功能,而硬件上天线做得十分简陋,竟然和很多廉价的USB无线网卡一样,把天线做到PCB上了(见后图解释)。天线功率很小,隔两堵墙信号就很差了。

正常使用的话,HG527-C就是一个Modem。用户只能是在电脑上拨号,非常麻烦。本人进行了一些尝试,在不改动firmware 的前提下,对该路由器进行了一些小改动,将HG527-C路由器的PPPoE拨号和路由功能释放出来。所以,说实在的,本文标题是忽悠人的,“整”这个路由器,既没有反汇编,也没有动态分析或者静态分析,不能算作真正的“Crack”。更准确的用词应该是“整”,或者“释放功能”

下面开始介绍“整”这个路由器的过程

1. 准备工作:将路由器彻底恢复至出厂状态。华为HG527-C路由器有一个隐藏的特权模式登录界面,地址是:http://192.168.1.1/CU.html。特权模式用户名和密码如下:

用户名:bjcnchgw
密码:8mCnC@bj
以特权模式登录,用户就可以配置PPPoE拨号和路由了。但是为了进入特权模式,需要一些准备工作。为什么呢?且听我慢慢道来。

华为HG527-C路由器支持一种叫TR069的电信网管协议。设备出厂时配置了一个默认的PPPoE链接,上电后,HG527-C会自动连接到联通的网管服务器。然后,联通的网管服务器会发出指令,修改默认的特权模式密码。这就是说,这个HG527-C路由器一旦插上电话线,特权模式密码就变了。我第一次用这台机器的时候就犯了这样的错误,导致无法登录特权模式。最让人郁闷的是使用机身上自带的reset也没有办法恢复默认的特权模式密码。

接下来,我们就来看看怎样恢复默认的特权模式密码。当然,如果你的HG527-C是刚刚拿回家,还没来得及插上电话线,那可以忽略此节内容。

好,那就开始吧。

为了恢复HG527-C的默认密码,我们需要从路由器的控制台登录。这个过程需要拆机。一般路由器硬件上都会提供两个串口,HG527-C也不例外。HG527-C的串口位置如下:

经我测试,HG527-C的两个串口中,有一个(上图中靠下面的,没有没有焊接铜针的那个)在量产产品中是禁用的,没有任何输出。另一个(上图中靠上的那个)使能了命令行。具体到每个串口的信号定义只能靠猜了。好在串口信号很少,有三根线就可以工作(TX,RX,GND)。这里介绍下“猜”的经验:可以先拿万用表,调到直流电压档,简单测一下,先把GND找出来。然后在调换TX,RX的位置试一下,很快就可以“猜”出来了。

需要注意的是,这个串口的电平标准遵循的是TTL标准,跟RS232不一样。如果直接接RS232串口的话,会发现电脑这边的串口只有输入,没有输出。需要采购或者DIY一根USB转TTL线。不贵,十块钱左右,淘宝上很多。

连接好的样子如下:

连接好以后就可以开机了。从开机提示信息来看,HG527-C的系统应该是uboot+linux,但是都裹得很严实。Linux的shell被换成了华为自己的路由器CLI界面,功能很受影响。华为CLI的用户名密码如下:

用户名:!!Huawei

密码:@HuaweiHgw

登录CLI界面后可以用swversion display命令查看软件版本信息,我的版本信息是这样的:

ATP>swversion display
HG527V100R001C02B015_BJCUC     #3 Fri Oct 15 12:12:57 CST 2010

用restoredefault命令可以恢复出厂Web特权模式密码配置。如下:

ATP>restoredefaultSuccess, the system shell is being reset. Please wait…
Reset system: reboot

好了,通过努力,我们终于将路由器完全恢复到了出厂状态。接下来就可以用默认的特权模式用户名和密码登录路由器,配置PPPoE拨号和路由功能了。

2. 配置ADSL PPPoE拨号

这里重复一下,HG527-C的特权模式登录方式如下:

地址:http://192.168.1.1/CU.html

用户名:bjcnchgw

密码:8mCnC@bj

PPPoE配置如下图所示:

3. 删除TR069相关配置

为了防止联通更改路由器特权模式密码,需要删除TR069相关配置。首先在“宽带设置”中选中名为“TR069_INTERNET_R_0”的链接,并将其删除。

另外还要删除“远程管理”相关配置。如下图所示:

4. 重启路由器,完成。

本来HG527-C只能当成一个“猫”用的,如果要多台电脑同时上网,还需要再买一个路由器。现在通过“整”,我们将HG527-C的路由功能释放出来,这样我们的家里就减少了一台用电设备。这不就是“节能减排”吗?

5. 关于TR069。这个需要好好研究一下。这个算是电信开放的网管协议了。需要了解一下TR069协议的安全性。为什么呢?因为也许有个家伙利用了网管系统的某个漏洞,也许他能搞得半个北京上不了网。

哈哈。

My alpha.

壮壮爸爸

Windows XP下PPTP客户端设置教程

首先在开始菜单打开控制面板,然后在控制面板里找到“网络链接”。双击“网络链接”,得到如下图像:

如上图所示,单击“创建一个新的连接”,进入下图所示界面:

单击“下一步”按钮,进入下图所示界面:

如上图所示,选择“连接到我的工作场所的网络”,然后单击下一步,进入如下界面:

如上图所示,选择网络链接的类型为“虚拟专用网络链接”,然后单击下一步,进入下图所示界面:

如上图所示,输入公司名,即链接表示名称。此处输入“strongpapa.info”以表示对本站的敬仰,感谢我,哈哈。

单击“下一步”,进入下图所示界面:

如上图所示,选择“不初始连接”,然后单击下一步,进入下图所示界面:

如上图所示,此处输入PPTP VPN服务器的地址。本站地址为:strongpapa.info。这里不得不敬仰我啦。

单击下一步,进入下图所示界面:

单击完成,VPN链接就创建好啦。

然后在桌面上双击新建的VPN链接图标,如下图所示,输入用户名和密码就可以上网啦。如下图所示:

虽然不是什么大作,鉴于截图如此费劲,还是敬仰我一下吧,^_^。

My alpha.

William.