2012年12月9日星期日

解压deb文件

Use 'ar t' to get a listing of the contents:

[rw@fever]/tmp $ar t xterm_222-1etch2_i386.deb
debian-binary
control.tar.gz
data.tar.gz

and 'ar x' to extract the components:

[rw@fever]/tmp $ar x xterm_222-1etch2_i386.deb data.tar.gz
[rw@fever]/tmp $tar tzf data.tar.gz
../
../usr/
../usr/bin/
../usr/bin/koi8rxterm
../usr/bin/lxterm
../usr/bin/resize
../usr/bin/uxterm

很给力吧

2012年11月26日星期一

calendar的相关python库

https://django-ics.readthedocs.org/en/latest/
http://pypi.python.org/pypi/django-ical
https://django-ics.readthedocs.org/en/latest/
http://dakrauth.com/blog/entry/announcing-django-swingtime/
https://github.com/dakrauth/django-swingtime/wiki
http://www.elfsternberg.com/2010/10/06/generating-ics-files-djangoevents/
http://uggedal.com/journal/creating-a-flexible-monthly-calendar-in-django/
http://icalendar.readthedocs.org/en/latest/
http://severinghaus.org/projects/icv/
http://vobject.skyhouseconsulting.com/
http://trac.calendarserver.org/
http://blog.thescoop.org/archives/2007/07/31/django-ical-and-vobject/
https://github.com/statesofpop/django-cal

2012年11月21日星期三

vs相关的资料

Predefined Macros

http://msdn.microsoft.com/en-us/library/vstudio/b0084kay.aspx

Frequently asked questions about the Standard C++ library

2012年11月7日星期三

Google SPDY介绍

转:http://blog.csdn.net/marcky/article/details/7728662
 
本文主要是参考Google SPDY项目主页的一些文档总结而来,目的整体上介绍SPDY协议的定义为主。后续,我将写一系列的文章分析SPDY的一些项目(如:Nginx),SPDY的性能测试以及如何部署SPDY到实际生产应用。

一、HTTP协议存在的一些主要问题

1、一个连接一个请求。浏览器和web server之间都是以短连接方式交互,一个连接只服务一次请求,对于一个需要加载多个资源的页面来说,将会带来很高的延迟。
2、只能由客户端发起请求,服务器完成响应。服务器不能主动的将一些必须的资源推送给客户端。
3、HTTP协议只能对body进行压缩处理,不能压缩header。在一个cookie较多的站点,将对带宽造成严重的浪费。

http的问题在10年前的web中,是无关紧要的。然而今天的web已不再像10年的web那般简单了,同时用户对web应用的体验要求也将是越来越高,所以Google发起了“Let's make the web faster“项目,SPDY正是此项目的一部分。

二、SPDY的目标
起初,SPDY项目并不只是为了加速http,更多的是要致力 于改进传输层和会话层协议。比如: Stream Control Transmission Protocol (SCTP), 一个用于替换TCP的传输层协议。除此之外还有一些其他方面的研究,可以在相应的white paper上找到。开发一个新的传输层协议也许很简单,但考虑到后期的部署、推广和兼容历史等因素,这估计是一个非常糟糕的决定,等待的结果必然是失败。 因此,目前的SPDY主要还是集中应用层协议的改进,加速HTTP。

SPDY的主要目标:
1、单个tcp连接支持并发的Http请求。这主要是解决目前http协议的一个连接只能服务一次请求的问题。
2、压缩请求/响应头。
3、定义spdy为一个相比http容易实现的协议。
4、使用ssl加密连接,用户数据更加安全的同时也解决了对已有网络体系的兼容问题。其实,TLS的强制,更多的是解决历史兼容问题,而不是安全考虑,后面详细介绍。
5、服务器可以主动的向客户端发起连接,并推送数据。

三、SPDY协议栈
在http协议栈中引入spdy后,大概就是下图(来自Google官方)的样子:



关键就是在tcp连接上面加入了spdy session层,这一层根据spdy draft又可以称为framing层,主要提供stream机制和消息组帧的实现。下文介绍具体协议的时候,再谈。

四、TLS-NPN
TLS-NPN全称是 Transport Layer Security - Next Protocol Negotiation,NPN是Google为了支持SPDY协议作为一个应用层协议使用,而为TLS定义的一个扩展。NPN扩展的出现仅仅是为了更好 的部署和使用SPDY,任何时候它都不会是SPDY的一部分。关于NPN扩展的详细介绍请看这里:http://technotes.googlecode.com/git/nextprotoneg.html 。

既然TLS-NPN并不是SPDY协议的一部分,那为什么要强制TLS?为何不能像HTTP一样根据用户自由选择是否SSL呢?Google这样做,必然是有道理的:
1、目前整个互联网可以说只有80和443两个端口可用,如果 SPDY跑在一个新的端口上提供web服务,就极有可能会被诸如防火墙等设施给阻止掉。要想推动整个网络系统引入一个新的等同于80和443的标准端口, 我想这绝对不是一件容易的事情,因此聪明的Google必须考虑兼容现在的网络体系环境,而不是自作聪明的推动新的端口。
2、放弃使用新端口的方案,就只能在80和443上面选择了。然而,目前很多的web中间代理设施只认80端口跑http协议,一旦SPDY跑在80端口上,必然会被这些代理给阻止掉。80端口显然也不能使用。
3、没了80端口,就只能选择443了,443目前是https协议加密数据传输,理论上443端口上经过加密的套接字可以传输任何应用层协议数据。
因此,为了在SSL上能够协商使用SPDY协议,Google就定义了NPN扩展,此扩展目前已经在OpenSSL、NSS等实现了。

五、SPDY-draft2
Google已经放出的SPDY协议草案在此: http://www.chromium.org/spdy/spdy-protocol ,目前已经到draft4了,但本文参考的是draft2,因为目前Nginx的SPDY实现是基于draft2而来。

SPDY在逻辑上由部分构成,一是framing layer,其主要负责组装帧消息,为了request/response提供基础;二是HTTP layer,它定义了request/response的相关行为。

根据上面这个简单的模型,从总体上看一下SPDY的3个重要组成部分——TCP connection、framing layer、http layer。
上图描述的是client和server之间的一个TCP连 接;这个TCP连接上面有两个stream,一个stream就负责了一次request/response;一个request/response由多 个frame(一个小箭头就是一个frame)组成;frame又分为了control frame (红色箭头)和data frame (蓝色箭头)。framing layer主要是定义一个frame消息,HTTP layer主要是定义request/response。

一次request/response完成后,就释放此 stream,但不会释放TCP connection。要发起新的request,首先得建立一个stream,由此可看出SPDY在TCP connection上加入了stream机制来模拟了http的短连接。stream其实只是TCP上面的一个逻辑层,它的建立和释放非常快,没有 TCP的多次握手,这就解决了TCP的Slow Start问题。换个角度想想,如果TCP connection的建立和释放本来就无延迟,非常的快速,那么http就没有改进的必要了,我猜想这也是一开始Google想从传输协议TCP入手解 决问题的考虑。

Framing
Framing分为control和data两种,下面详细介绍SPDY定义了哪些control frame和data frame,他们的作用是什么。

control frame结构

  +----------------------------------+
  |C| Version(15bits) | Type(16bits) |
  +----------------------------------+
  | Flags (8)  |  Length (24 bits)   |
  +----------------------------------+
  |               Data               |
  +----------------------------------+

上图可以看到一个control frame至少有8个字节的头部信息。
C:           占一个bit,用来识别此frame是control还是data之用。
Version:  占15个bit,是SPDY的版本号,目前是2。
Type:      占16个bit,control frame的类型,表示此control frame具体是干什么用,后面将介绍每种类型的control frame。
Flags:      占8个bit,一个附加的属性域。
Length:   占24个bit,其实是一个无符号的24位整数,表示Length域后面的数据长度。


data frame结构
  +----------------------------------+
  |C|       Stream-ID (31bits)       |
  +----------------------------------+
  | Flags (8)  |  Length (24 bits)   |
  +----------------------------------+
  |               Data               |
  +----------------------------------+

同样可以看出一个data frame至少也有8个字节的头部信息。
C:                    同control frame。
Stream-ID:       占31bit,一个stream的标志id。
Flags和Length: 同control frame。

stream
SPDY 的一个stream既可以被client创建,也可以被server创建,这就说明SPDY不但允许由client发起请求,也可以由server发起请 求。如果你愿意,还可以创建一个单向stream,只需要发送特定的control frame就可以了,单向stream可以认为是只有请求,永远不会有响应。stream的创建、关闭等操作都是由control frame实现的。

control frames 
SPDY定义了不少的control frames,这里简单的列举一下它们,不作详细的介绍,如果你在实现SPDY的时候,请求看具体draft。

SYN_STREAM control frame - 是发送者用来创建一个stream。
SYN_REPLY control frame - SYN_STREAM接受者用此control frame去开始响应对方。
RST_STREAM control frame - 可以用来中断一个stream。
SETTINGS control frame - 可以用来改变一个stream的状态,属性等。
NOOP control frame - 是一个无操作的control frame了,接受者直接忽略它。
PING control frame - 类似ping命令的功能,可以用来测量一个rtt时间。ping工具是工作在4层,此处的PING control frame却是工作在7层上。
GOAWAY control frame - 发送者用来告诉对端,不再接受新的stream了。可以理解为不久将要关键当前的TCP connection。
HEADERS control frame - 给stream添加一些附加的header。

到此,各种control frame都简单的介绍完了,每个frame的具体定义还得参考draft。至于datat frame,相比control frame就简单多了,它没有这么类型,它只做一件事情——就是在某个stream上传输数据。

HTTP layer
为了兼容目前的所有应用,尽量做到应用不做任何修改,或者尽可能少的修改。因此http layer定义了如何将http request/response跑在framing之上。

客 户端通过SYN_STREAM control frame发起一个请求,请求相关的所有header放在SYN_STREAM frame中发送,如果请求有body将在data frame中发送,最后一个data frame必须设置FIN_FLAG标志请求结束。
服务器通过SYN_REPLY control frame响应客户端,响应的所有header放在SYN_REPLY frame中发送,响应数据通过data frame来发送,同样最后一个data frame需要设置FIN_FLAG标志响应结束。

SPDY还详细的定义http request/response headers的异同,具体看草案。

server push
有了push功能就可以针对一个客户端请求响应多个应答,这样可以避免针对每个资源的获取,客户端都要主动来请求一次;相反,服务器主动将这样一些明知客户端需要的资源推送给客户端。push功能的实现感觉还是挺复杂的,具体参考spdy-draft。

SPDY 部署
1、服务器通过Alternate-Protocol header来建议使用SPDY
服务器收到一个普通的http请求的时候,可以通过在响应 header里添加Alternate-Protocl来告知客户端可以发送SPDY。客户端收到Alternate-Protocl header后,就尝试去通过SPDY发送请求给服务器,如果失败了,在当前域下,就再也不要去尝试做这件事情了。

2、服务器通过TLS-NPN扩展来建议使用SPDY
服务器在443端口收到一个携带有TLS-NPN扩展的连接, 就告诉客户端自己所支持的spdy版本号,然后客户端就通过SPDY来和服务器通信。通过TLS-NPN扩展的方式应该是唯一的途径在整个互联网上使用。 Alternate-Protocol的方式只有在确定客户端和服务器中间没有拒绝其他端口的防火墙等设施才ok。

SPDY的现状
目前Google,twitter,facebook等公司都 已经开始着手部署spdy来加速自己的web应用了。在服务器方面,Apache、Nginx、Netty、Jetty、node.js等都已经开始初步 的支持SPDY。浏览器方面,chrome已经支持SPDY,firefox貌似也开始支持了。其次,在github上搜索一下SPDY,可以看到有不少 spdy的项目存在了。

2012年11月5日星期一

开源cms和bbb整合

http://typo3.org/home/

http://typo3.org/extensions/repository/view/oblady_bigbluebutton

网络工具教程

http://books.google.com.hk/books?id=Tw11QSUGbKwC&pg=PA229&dq=nistspy&hl=zh-CN&ei=NxbaTaCDCIO8vQOilP2dCQ&sa=X&oi=book_result&ct=result&resnum=1&ved=0CC4Q6AEwAA#v=snippet&q=cos&f=false

搭建自己的ip电话环境

参考 http://www.internet2.edu/sip.edu/

rtmpt的相关链接

http://red5.5842.n7.nabble.com/RTMFP-in-red5-legal-td3630.html#a32760305
http://code.google.com/p/blue5/wiki/RTMPFPSpecs
https://github.com/OpenRTMFP/Cumulus

2012年11月1日星期四

编译最新Kernel

http://blog.csdn.net/deansrk/article/details/6674025

http://hi.baidu.com/adomore/item/7580f5e6543539f92a09a4ad

http://hi.baidu.com/linuxtrip/item/5e8e6153dd63ce9c8c12ed9b

http://kerry.blog.51cto.com/172631/398554

http://hi.baidu.com/higkoo/item/f7fb0d0110325310cc34eac3

http://hi.baidu.com/uwtzubraqinrvxr/item/9527a9c7f86de220a1b50a56

http://www.idcrx.com/zhishiku/linux/2012/0601/163108.html

http://funky-dennis.livejournal.com/3290.html

http://blog.csdn.net/firedfish/article/details/4392556

http://en.linuxreviews.org/Kernel_Rebuild_Guide

--------------------------------------------------------
1. wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.6.5.tar.bz2; cp linux-3.6.5.tar.bz2 /usr/src/

2. cd /usr/src/;tar jxvf linux-3.6.5.tar.bz2

3. mv /usr/include/linux /usr/include/linux.old;ln -s /usr/src/linux-3.6.5/include/linux/ /usr/include/linux

4. cd linux-3.6.5;cp /boot/config-`uname -r` .config

5. yum install ncurses ncurses-devel;make menuconfig

    You can choose the features you want to enable, for example, I've chosen Controlled Delay AQM(CoDel) in "Networking support -> Networking options->QoS and fair queueing)

6. edit ".config", find CONFIG_SYSFS_DEPRECATED, and add:

CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y

7. make;make modules_install;make install

8. mkdir /tmp/mylinux;cp /boot/initrd-3.6.5.img /tmp/mylinux/initrd-3.6.5.img.gz;cd /tmp/mylinux/;

9. gunzip initrd-3.6.5.img.gz;cpio -id < initrd-3.6.5.img

10. edit init, and comment out the following two duplicate lines:

#echo "Loading dm-region-hash.ko module"
#insmod /lib/dm-region-hash.ko

11. find .|cpio -c -o|gzip  -9 > /boot/initrd-3.6.5.img

12. edit /boot/grub/grub.conf, change default to 0(use the new kernel as the default)

Done, reboot

--------------------------------------------------------
1. 去http://www.kernel.org/下载最新的稳定版本

cp /boot/config-`uname -r` .config
 
make menuconfig #choose enable deprecated sysfs features to support old userspace tools

执行完make menuconfig后,修改/usr/src/linux-2.6.35.4/.config
将#CONFIG_SYSFS_DEPRECATED is not set
默认被注释掉的,将其改为y。即修改为


CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y

make

make modules_install

mkdir  /tmp/mylinux
         
cp  /boot/initrd-3.2.9.img  /tmp/mylinux/initrd-3.2.9.img.gz
         
cd  /tmp/mylinux
         
gunzip  initrd-3.2.9.img.gz
         
cpio  -id  < initrd-3.2.9.img

remove duplicate in "init",去掉后面的。

   echo "Loading dm-region-hash.ko module"
   insmod /lib/dm-region-hash.ko

find  .  |  cpio  -c -o |  gzip  -9 > /boot/initrd-3.2.9.img

2012年10月29日星期一

利用Xapian构建自己的 搜索

http://www.162cm.com/p/xapian-learning.html

linux磁盘空间查看利器

http://dev.yorhel.nl/ncdu

使用方法:

执行ncdu会提示选择目录,输入目标目录,回车,即可列出当前目录下的文件及目录的大小,默认按照大小进行排序

可以使用“?”调出帮助菜单

使用数字键,1、2、3进行切换,1为快捷键,2为显示格式说明,3为ncdu版权信息。

常用快捷键

n :按文件名进行排序
s :按文件大小进行排序
r :重新统计当前文件夹大小
g :用#或百分比显示各文件/目录的大小所占的百分比
i :显示当前文件/目录信息
d :删除
ncdu /
可以看整个硬盘的空间使用

推荐系统

Deconstructing Recommender Systems, http://spectrum.ieee.org/computing/software/deconstructing-recommender-systems 这是一篇推荐系统综述的文章,介绍了推荐系统的基本算法及其演化过程,推荐系统的现状和面临的问题。 Grouplens: 最早研究推荐系统的机构之一,http://www.grouplens.org/ MIT的推荐系统Ringo, http://www.sigchi.org/chi95/proceedings/papers/us_bdy.htm

2012年10月14日星期日

Linux traffic control - the basics

Linux traffic control的基本介绍,包括一些基本概念,命令参数的含义


http://www.docum.org/docum.org/faq/cache/1.html

2012年10月10日星期三

Wireshark包解析器扩展

可以通过Lua来写扩展,可以通过C。Lua更加方便点。先记录几个链接。

http://wiki.wireshark.org/Lua

http://wiki.wireshark.org/LuaAPI/

http://wiki.wireshark.org/Lua/Examples

http://www.codeproject.com/Articles/19426/Creating-Your-Own-Custom-Wireshark-Dissector

Lua教程:

http://www.lua.org/pil/

http://onlamp.com/pub/a/onlamp/2006/02/16/introducing-lua.html

http://lua-users.org/wiki/SampleCode

2012年8月20日星期一

CBQ限速

CBQ(Class based Queuing)是classful的限速工具。CBQ的主要工作原理是调整包之间的时间间隔来达到限速的目的。比如10mbit/s的链路要限制为1mbit/s,那么就有90%的时间是空闲的。这种方式需要预先的知道链路的capacity。

原理:

CBQ会统计链路的idle时间(moving_avg),并将这个同理论计算的idle时间比较,idle_moving_avg - idle_target = avgidle,理想情况下avgidle是0,如果链路过载,那么avgidle就是负值,CBQ会限制发送一段时间,如果长时间不发生数据,那么avgidle就会变大,这种情况下就会有一些burst,为了限制burst,就需要设置maxidle.

idle时间的衡量在实现中是用的设备驱动的数据请求之间的jiffies.

参数:

avgpkt - 包的平均大小,字节数。这个用来计算maxidle。

bandwidth - 链路的capacity,用来计算理论idle时间

cell - 计算包的传输时延时用到,cell作为包大小的基本单位,默认为8。例如:800byte和806byte的包的传输时延都一样。

maxburst - 突发流量的设置,这里是设置包的个数,maxidle不能直接设置,只能通过这个参数设置。

minburst - CBQ在流量过载时,理想情况下是在计算的每个idle时间点只发送一个包,但内核的时间精度有限制,所以只能选择在相对长一点的时间内多一次性的多发送一些数据包。minburst设置的越大,那么在长时间内的流控就越准,但会带来瞬间的突发流量。

minidle - CBQ在流量过载时,avgidle小于0,再次发生数据要等到avgidle恢复到某个比较大的值,如果之前的流量有很大的突发,这段时间可能会很长。如果指定minidle,就可以防止avgidle出现过小的情况。Minidle的单位是us(microseconds), 设置为10表示-10us。

mpu - 最小包单元的字节数,因为即便payload是0, ethernet的包长度必须填充为64字节,也是需要时间来传输的,这个用来精确的计算idle时间。

rate - 要限制的带宽。

CBQ的class特性:

CBQ也可以组织成树形结构,每个class是一个节点,可以设置优先级,优先级小的优先调度,调度采用WWR(weighted round robin)方式,下面是相关的一些参数:

allot - 每次调度可以发送的字节数(最小单元)。一个class一轮可以调度多次,根据weight来。

prio - 优先级

weight - 权值,最终会做归一化处理,一般采用10分制。renormalized weight和alloc的乘积就是每轮调度该class能发生的字节数。

CBQ的带宽共享:

isolated - 不借给子节点class带宽

sharing - 可以借给字节的class带宽,默认值。

bounded - 不去借用父节点class带宽

borrow - 可以借用父节点class带宽,默认值。


例子:

               1:           root qdisc
               |
              1:1           child class
             /   \
            /     \
          1:3     1:4       leaf classes
           |       |
          30:     40:       qdiscs
         (sfq)   (sfq)
 
在这个例子中,给http 5mbit,给smtp 3mbit,他们加起来不超过6 mbit/s, 并且他们直接可以共享带宽。
链路的capacity是100mbit。
 
1)设置root节点,设置为bounded那么带宽就不会超出6 mbit.
 
# tc qdisc add dev eth0 root handle 1:0 cbq bandwidth 100Mbit         \
  avpkt 1000 cell 8
# tc class add dev eth0 parent 1:0 classid 1:1 cbq bandwidth 100Mbit  \
  rate 6Mbit weight 0.6Mbit prio 8 allot 1514 cell 8 maxburst 20      \
  avpkt 1000 bounded 
 
2) 设置两个叶子节点:
 
# tc class add dev eth0 parent 1:1 classid 1:3 cbq bandwidth 100Mbit  \
  rate 5Mbit weight 0.5Mbit prio 5 allot 1514 cell 8 maxburst 20      \
  avpkt 1000                       
# tc class add dev eth0 parent 1:1 classid 1:4 cbq bandwidth 100Mbit  \
  rate 3Mbit weight 0.3Mbit prio 5 allot 1514 cell 8 maxburst 20      \
  avpkt 1000 

4)采用SFQ替换FIFO,达到流间调度的公平性。
 
# tc qdisc add dev eth0 parent 1:3 handle 30: sfq
# tc qdisc add dev eth0 parent 1:4 handle 40: sfq
 
5)加入过滤,针对特定的协议端口:
 
# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 80 0xffff flowid 1:3
# tc filter add dev eth0 parent 1:0 protocol ip prio 1 u32 match ip \
  sport 25 0xffff flowid 1:4 
 
 
工具: 

CentOS/Redhat默认已经带了一个cbq的工具,相关的配置在/etc/sysconf/cbq,shell脚本在sbin/cbq下.

2012年7月30日星期一

linux维护常用命令

du -sm /tmp/* | sort -nr

ssh连接被远程关闭解决方案

This works for me:
# cd ~/.ssh
# ssh-keygen -t rsa -f id_rsa
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa.
Your public key has been saved in id_rsa.pub.
The key fingerprint is:
xx:xx:xx:08:d1:d1:29:da:29:8b:8f:c3:de:xx:xx:xx user@system
Log in as the intended user on the target machine. Add the public key
(id_rsa.pub) to ~/.ssh/authorized_keys. The file should look something
like this.
ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAIEAtfjDtf/xhw2trKYAJ61MmzADkG+0ma7DrvIqjoRUswfPglRWrbDpD+An
A72dzJB8UcLCMB0jyEhNz3yN/tH8FQ4JAHQDDWyt47wAqf1PZGxxsXxxxxxxxxxxkx1ke4PM17rH5IK7uxJ5AnOU8jCJvXUxbdaYdReWnBSpInJHotE=
root@system
Note that this is all on one line. If you accidentally split it over
multiple lines, you'll get something like this:
# scp file user@system:/tmp
Connection closed by 10.10.16.10
lost connection
On system, you'll see something like the error below in /var/adm/messages
Jul  7 11:48:18 system sshd[26022]: [ID 800047 auth.crit] fatal:
buffer_get: trying to get more bytes 129 than in buffer 34

2012年7月7日星期六

top vi command

http://www.oualline.com/vim/10/top_10.html

比较有用的
split - 分割多窗口

v - 可视化模式

> - 右缩进

ctrl-q - 进入列模式

cindent - 自动用c的缩进

make - 执行make,按:cn跳到下一个错误,:cc查看当前错误

ctags - 生成索引文件(支持多种编程语言), vim -t a_function,直接打开a_function的定义文件,并跳到定义处。ctrl-]可以跳到函数定义,ctrl=T跳回调用处。

ab - 定义缩写宏,vi会自动替换

智能补齐,ctrl+p, ctrl+n

复合搜索,/;/分割,/{file}+1/;/echo/

重放搜索, :%s/^\(Martin\)/Mr \1 Wicks/g

切换大小写, Escape [n] ~

截取特定行另存,:6,9w >> /tmp/newfile

标记行光标移到该行上,键入mx(x 是任何一个小写字母)就可以了。`x可以跳到指定标记处。··跳到上一个标记处。


撤消上一个编辑操作。       U

重复上一个编辑操作。     .


还原被撤消的编辑操作。   Ctrl   +   R

2012年6月20日星期三

vim的空格tab配置

vim中shiftwidth, tabstop, softtabstop和expandtab的意义

from: ludonghai715
1 shiftwidth
这个是用于程序中自动缩进所使用的空白长度指示的。一般来说为了保持程序的美观,和下面的参数最好一致。同时它也是符号移位长度的制定者。
2 tabstop定 义tab所等同的空格长度,一般来说最好设置成8,因为如果是其它值的话,可能引起文件在打印之类的场合中看起来很别扭。除非你设置 了 expandtab模式,也就是把tabs转换成空格,这样的话就不会一起混淆,不过毕竟制表符为8是最常用最普遍的设置,所以一般还是不要改。
3 softtabstop如 果我们希望改变程序中的缩进怎么办?shiftwidth和tabstop不一样的话,你会发现程序比较难看的。这时候,softtabstop就起作用 了。可以从vim的说明中看到,一旦设置了softtabstop的值时,你按下tab键,插入的是空格和tab制表符的混合,具体如何混合取决于你设定 的softtabstop,举个例子,如果设定softtabstop=8, 那么按下tab键,插入的就是正常的一个制表符;如果设定 softtabstop=16,那么插入的就是两个制表符;如果softtabstop=12,那么插入的就是一个制表符加上4个空格;如 果 softtabstop=4呢?那么一开始,插入的就是4个空格,此时一旦你再按下一次tab,这次的四个空格就会和上次的四个空格组合起来变成一个 制表符。换句话说,softtabstop是“逢8空格进1制表符”,前提是你tabstop=8。
4 关于expandtab举个例子,在多人一起开发项目时,为了使代码风格尽量保持一致,一般不允许在代码使用TAB符,而以4个空格代之。我们可以编辑一个文件,包含下面的内容:
set shiftwidth=4
set expandtab
然后把下面的命令加入到.vimrc中:
autocmd FileType c,cpp set shiftwidth=4 | set expandtab
就可以只在编辑c和cpp文件时实行这种设置了


set autoindent ruler 启用自动缩进
filetype plugin indent on 允许载入indent插件
再set 查看下syntax与shiftwidth的值,syntax应为javascript shiftwidth为2, 4, 8等

2012年6月15日星期五

pywin32 xp下安装错误

在 python 中 import win32api 时出现

?
>>> import win32api
Traceback (most recent call last):
  File "", line 1, in
ImportError: DLL load failed: 找不到指定的模块。
>>>
解决方法:
拷贝
C:\Python26\Lib\site-packages\pywin32_system32\*

C:\Windows\System32

2012年6月13日星期三

gdb thread

info threads 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程。 thread ID 切换当前调试的线程为指定ID的线程。 break thread_test.c:123 thread all在所有线程中相应的行上设置断点thread apply ID1 ID2 command 让一个或者多个线程执行GDB命令command。 thread apply all command 让所有被调试线程执行GDB命令command。 set scheduler-locking off|on|step 估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试 程序执行呢?通过这个命令就可以实现这个需求。off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

2012年6月10日星期日

宏编译错误的解决

g++ -I../h -DENABLE_TRACE_LEVEL  -E ../h/CmTraceFromT120.h  > error

然后去error里去看看就知道了

2012年6月8日星期五

python导入出问题解决方案

没别的,路径问题,查看环境变量设置是否正确。

另外,通过这个命令查看路径

python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"

其实就是sys.exec_prefix

另外,
error: AccessInit: hash collision: 3 for both 1 and 1.
这个问题,也是PYTHONPATH设置的问题,
设置为如下“c:\python26\Lib"就可以。其他OS类似。 

2012年5月24日星期四

编程语言教学项目

1. http://pleac.sourceforge.net/ 各种语言的教程,看了一下python,还不错。

2. https://learn-python-the-hard-way-zh_cn-translation.readthedocs.org/en/1.0/intro_zh.html

3. http://www.codecademy.com/ 现在有python,ruby,web,javascript/jquery等,有空可以学习一下。

javascript的原型继承

参考:
http://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/
http://javascript.crockford.com/inheritance.html

1. 原型继承的所谓原型是一个对象。
2. javascript的function才有prototype属性,这个属性存储的是原型对象的引用,这个主要是为了创建对象时,使用原型对象进行初始化新对象。
3. 在实现中,如firefox,每个对象都有一个__proto__的属性(function也是一个对象,继承的原型是Function)。这个属性也是指向原型对象的引用,只不过是由javascript内部维护的,在创建新对象时,javascript内部会将其赋值为prototype属性(this.__proto__ = fn.prototype, fn为声明的function名称),当访问对象的变量或方法时,如果该对象没有声明次变量或方法,则去__proto__指向的原型对象中去找。prototype属性只是提供给javascript的使用者提供的一个设置原型对象的途径,所有的类似访问对象,或instanceof之类的操作,都是依赖__proto__属性完成的,所以,如果把prototype属性重新复制为一个新的对象,由于是通过__proto__去找的,所以如果不相应的修改__proto__,是找不到对应的属性的。(具体见下面的例子)


01var A = function(name) {
02    this.name = name;
03}
04
05var a = new A('alpha');
06a.name; //'alpha'
07
08A.prototype.x = 23;
09
10a.x; //23

01var A = function(name) {
02    this.name = name;
03}
04
05var a = new A('alpha');
06a.name; //'alpha'
07
08A.prototype = {x:23};
09
10a.x; //null

2012年4月12日星期四

git基本用法


git的特点

git并不是存差异,而是存储完整的文件
git是分布式的,不用中心服务器
git的工作目录中的文件可以随时的从git目录".git"中的不同分支之间切换
git提交的不是当前工作目录的改动,需要手工的把改动提交到Index中,有三种状态: staged-已经提交到Index中的改动;modified-已经改动但没提交到Index中(之前已经提交到Index过);untracked-未加入到Index中改动。

git的概念

blob - 文件,存储文件内容
tree  - 目录, 指向tree或者blob
commit - 指向一个tree,标记当前的状态,记录元信息(作者,提交者,时间戳,之前的commit等)
tag - 用来给commit做标记

git的配置


git安装完后第一步是设置全局配置项,这个可以在用户目录下的.gitconfig文件下配置,包括user, email和autocrlf

git config --global core.autocrlf false#禁用换行自动转换
git config --global core.autocrlf input#开启输入换行自动转换,在提交时会将CRLF自动转换为LF
git config --global user.name "Jeromy Fu"
git config --global user.name "fuji246@gmail.com"

如果不是配置全局的,仅仅针对具体的项目配置,去掉上面的--global即可。 git有多种访问方式,git,http,ssh,git的效率更高,但http可以穿越防火墙。

git基本操作


git init -初始化仓库

git add file1 file2 -添加文件到Index(还未提交)

git diff -显示当前的改动(包括还未添加到Index中的)

git diff --cached -显示当前待提交(staged)的改动

git status -查看staged, modified和untracked的改动

git commit -提交Index中的改动到仓库

git commit -a -针对当前所有的改动(不包括新文件)一步完成git add和git commit的操作

在提交后,需要添加一些comment,最好的格式是第一行写一个概括性的描写,然后空格,然后是详细的描述,很多工具根据这个规则来将第一行作为邮件标题,详细描述作为邮件正文。

之前的一些工具新文件都是需要通过add命令来添加的,git的add也能添加新文件,但意义不太一样,是添加文件到Index中。

git branch branchname -添加新的分支

git branch -列出当前的所有的分支,并标识当前所在的分支

git checkout branchname -从git目录中(.git)取出branchname对应的分支

这里如果在创建分支之前文件已经更改,但还未提交,那么在checkout刚创建的分支时会自动合并文件。

git merge branchname -将当前分支和branchname分支合并

如果上面的merge有冲突,需要解决冲突再提交。可以使用git diff查看冲突

gitk - 显示当前分支改动的历史图示

git branch -d branchname -删除branchname的分支,(当前必须在其他分支),如果branchname的分支有未合并到当前分支(不一定是master)的内容,那么删除会失败,这个会确保branchname分支的内容会合并到其他的某个分支。

git branch -D branchname -强制删除branchname的分支
git diff -显示当前工作目录还未提交到Index中的改动,modified的。

git diff --cached -显示当前工作目录中已经提交到Index中的改动,staged的。

git diff HEAD -显示当前工作目录中所有改动,除untracked之外的。

git clone [uri] [dir] -克隆一个工程

git pull [uri] [branch] -从uri的特定分支拉代码,会自动合并

git remote add [name] [uri] -给远程的uri指定一个名称

git fetch [name]/[uri] -从uri的特定分支拉代码,不会自动合并。

git branch -r -查看远程的branch



git reset --hard 如果使用git init,push后需要使用这个命令才能看到新的内容,最好用git --bare init

git checkout -- file1 // 使用暂存区快照恢复工作目录文件,工作目录的文件修改被抛弃。
git reset HEAD file1 // 取消暂存区的文件快照


git clone后分支缺失,保存下面的shell脚本并执行,

#!/bin/bash
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do
    git branch --track ${branch##*/} $branch
done


参考:http://stackoverflow.com/questions/67699/how-do-i-clone-all-remote-branches-with-git


Git bare 和 non-bare 仓库 :
简单的说,bare的方式类似集中式的仓库,没有工作目录(working copy)。默认的
git init
创建的是non-bare的仓库,如果从其他地方push到这个non-bare的仓库,那么当前目录是不会出现最新的代码的,需要使用
git reset --hard
才能更新到最新的内容到当前工作目录。如果是作为中心仓库服务器,那么使用
git --bare init
来初始化仓库。

两者间转换:

bare -> non-bare: clone后删除之前的bare的就可以了
non-bare -> bare:
git clone --bare -l non_bare_repo new_bare_repo

参考链接:

http://sitaramc.github.com/concepts/bare.html
http://www.bitflop.com/document/111
 

2012年4月8日星期日

charset encoding guess

bigbluebutton上传txt文件有乱码,根本原因是openoffice不知道txt的编码,看了一下,有些第三方的工具可以猜测编码。另外关于编码的问题,可以参考

http://blogs.msdn.com/b/michkap/archive/2005/01/30/363308.aspx
http://blogs.msdn.com/b/oldnewthing/archive/2007/04/17/2158334.aspx

猜编码的开源项目
http://docs.codehaus.org/display/GUESSENC/Home(这个不猜,参考)
http://code.google.com/p/juniversalchardet/
http://jchardet.sourceforge.net/
http://site.icu-project.org/
http://cpdetector.sourceforge.net/
http://tika.apache.org/1.1/api/org/apache/tika/language/LanguageIdentifier.html

看介绍说juniversalchardet比jchardet准确率更高,打算先用这个试试看。

试用了一下,可以识别,还比较好用,准备给bbb提交patch了

2012年3月25日星期日

How to talk to the Modem with AT commands[转]


asterisk的chan_celliax,使用了AT commands来和phone交互。

http://www.asteriskwin32.com/chan_celliax.php

 

http://forum.xda-developers.com/showthread.php?t=1471241



2012年3月23日星期五

什么是Caller ID[转]

Caller ID

                                       Caller ID
      Your phone rings. A name pops upon on your phone's screen. It's the name and number of the person calling you. Actually, it's the originating telephone number and the name the phone company thinks is the subscriber. The originating telephone number is stored in the originating central office equipment register, which is a database. That number supports a further database lookup, which associates the directory listing, assuming that the originating number is listed (i.e., not unlisted, or "nonpub" for nonpublished). The name and number information is passed through the local and long distance networks, and appears on your Caller ID box or your display telephone between the first and second rings.
      The delivery of Caller ID information assumes several things. First, the entire network of switches must be supported by SS7 (Signaling System System #7). Second, the calling party must originate the call from a single-channel line, rather than a multichannel trunk (e.g., T-1). Third, the originating line/caller must not block the transmission of the information. If all of these criteria are not met, your Caller ID box will display "ANONYMOUS" or "NOT AVAILABLE." Caller ID is one of several CLASS (Custom Local Area Signaling Services) provided by your LEC (Local Exchange Carrier). There generally is both a small installation charge and a monthly charge for Caller ID. Caller ID lets you amaze your parents and scare your technophobic friends, when you answer the phone with something like "Hi, Harry! Great Dictionary!" Caller ID also helps you avoid those dinnertime calls from telemarketers. They always block their numbers. By the way, Caller ID is not the same as ANI, although they often are confused. See also ANI, Caller ID Message Format (for a very detailed explanation), and CLASS.
来电显示
      你的电话振铃。你的电话机屏幕上跳出一个名称。正是呼叫你的人的名称和电话号码。事实上,这正是电话公司认为的该用户的初始电话号码和名称。这个初始电话 号码被存储在最初的市话局设备寄存器,也就是数据库中。这个电话号码支持与号码指南列表相关联的进一步的数据库查询,假设这个初始号码被列在指南里面(即 没有未被列入或者是未被出版“nonpub”)。名称和号码信息通过本地和长途网络传输,出现在你的来电显示器上或者是你的第一次和第二次振铃之间的显示 电话机上。
      来电显示信息的传输假定了几种情况。首先,整个交换机网络必须支持 SS7(系统 7 号信令)。第二,主叫方必须从一个单信道线路而不是多信道中继线(即 T-1)发起呼叫。第三,主叫线路/呼叫方不得阻碍该信息的传输。如果这些标准全部不能满足,那么你的来电显示器上将显示“匿名”或者是“无效”。来电号 码是你的LEC(本地电话公司)提供的几种CLASS(客户本地信令服务)中的一种。通常来电显示有一小笔安装费和月租费。当你接起电话时说 “嗨,Harry,字典编的不错!”时,你会让你的父母吃一惊,也会让你的工学院朋友吓一跳。来电显示功能也会让你避免在吃饭时间接到来自电信市场的电 话。他们总是隐藏自己的电话号码。顺便说一句,来电显示与ANI不一样,尽管这两者总是容易搞混。参见 ANI、Caller ID Message Format (解释的非常详细)和 CLASS。
Caller ID Message Format
      Calling Number Delivery (CND) came about as an extension of Automatic Number Identification (ANI). ANI is a method that is used by telephone companies to identify the billing account for a toll call. Although ANI is not the service that provides the information for CID, it was the first to offer caller information to authorized parties. The CID service became possible with the implementation of Signaling System 7 (SS7). The CID information is transmitted on the subscriber loop using frequency shift keyed (FSK) modem tones. These FSK modem tones are used to transmit the display message in American Standard Code for Information Interchange (ASCII) character code form. The transmission of the display message takes place between the first and second ring. The information sent includes the date, time, and calling number. The name associated with the calling number is sometimes included also. Since the time CID was first made available, it has been expanded to offer CID on Call Waiting (CIDCW) as well. With CIDCW, the call waiting tone is heard and the identification of the second call is seen. In earlier editions of my dictionary, I included the complete formatting, down to individual bits. It's too technical for this dictionary. However, if you want the entire story in all its detail, go to http://www.testmark.com/develop/tml_callerid_cnt.html and read the article on "Caller ID Basics", by Michael W. Slawson of Intertek Testing Services, TestMark Laboratories. Michael has assured me that he will leave his excellent paper on the Web forever.
来电显示信息(CID)格式
      主叫号码传送(CND)是自动号码识别(ANI)的一个扩展功能。ANI是电话公司用来识别长途电话呼叫账单的一种方法。尽管 ANI 并不为 CID 提供信息服务,但是也是第一个为获得授权的被叫方提供主叫方信息的。使用7号信号系统后就可以提供 CID 服务了。使用移频键控(FSK)调制解调器音频可以在用户环路上传输 CID 信息。这些 FSK 调制解调器音频可以以美国信息交换标准码(ASCII)字符代码形式传输显示信息。显示信息的传输发生在第一次和第二次振铃之间。信息传输包括日期、时间 和主叫号码。与主叫号码相关的主叫方名称有时也包括在内。由于是第一次使用,因此对 CID 功能进行了扩展,同时还提供呼叫等待来电显示信息(CIDCW)。使用了 CIDCW,可以听到呼叫等待音,并且第二次呼叫的识别号也可以看到。在我这本辞典的早期版本中,我收纳了完整的格式,直到单个的比特。对这本辞典来说, 太专业了。然而,如果你希望看到所有详细的解释,可以查阅 http://www.testmark.comdevelop/tml_callerid_cnt.html,阅读“来电显示基础”一文,作者是 TestMark实验室 Intertek 测试服务中心的 Michael W. Slawson。Michael 已经向我保证了,他将永远在网站上留下他精彩的论文。

2012年3月22日星期四

关于协同编辑

协调编辑在某些情况下还是很有用的。

收集了一些资料, 有多种实现的方式,具体见Technical challenge, http://en.wikipedia.org/wiki/Collaborative_real-time_editor

CoEditor
----------

http://vhost1597.developer.ihost.com:8080/cowebx-apps/coedit/index.html
https://github.com/opencoweb

Client-side
Less than 2000 lines of Dojo-powered javascript

Server-side
A python web server capable of Operational Transformation, powered by the Open Cooperative Web Framework
 
https://github.com/opencoweb  
 
Gobby
-------------------
 
Gobby is a free collaborative editor supporting multiple documents in one session and a multi-user chat. It runs on Microsoft Windows, Mac OS X, Linux and other Unix-like platforms. 

http://gobby.0x539.de/trac/
 
moonedit
-------------

http://moonedit.com/

Mozilla Skywriter 
---------------------
 
https://github.com/mozilla/skywriter 
 
 
ACE
-------------
 
http://sourceforge.net/projects/ace/
 

EtherPad
---------------

有两个版本,算两个完全不同的实现吧。

http://en.wikipedia.org/wiki/EtherPad
http://etherpad.org/
http://code.google.com/p/etherpad/
https://github.com/ether/pad
https://github.com/pita/etherpad-lite

mobwrite
--------------
http://code.google.com/p/google-mobwrite/
 
 
协同编辑的理论基础
-------------------------
 
Operational transformation (OT) is a technology for supporting a range of collaboration functionalities in advanced groupware systems.  
 
http://en.wikipedia.org/wiki/Operational_transformation#OT_Control_.28Integration.29_Algorithms
 
 
最后,协同工作的理论
---------------------------
computer-supported cooperative work (CSCW)  

http://en.wikipedia.org/wiki/Computer_Supported_Cooperative_Work

2012年3月15日星期四

SCTP介绍

SCTP在功能上介于TCP和UDP之前,比TCP轻量级,但比UDP功能强。另外还有multi-home功能支持,能合理利用本地的多个接入网络。

http://tdrwww.exp-math.uni-essen.de/inhalt/forschung/sctp_fb/sctp_intro.html

http://www.bluestop.org/SctpDrv/

2012年3月14日星期三

关于ATM cell的一段描述[转]

Why cells?

Consider a speech signal reduced to packets, and forced to share a link with bursty data traffic (traffic with some large data packets). No matter how small the speech packets could be made, they would always encounter full-size data packets, and under normal queuing conditions, might experience maximum queuing delays. That is why all packets, or "cells," should have the same small size. In addition the fixed cell structure means that ATM can be readily switched by hardware without the inherent delays introduced by software switched and routed frames.
Thus, the designers of ATM utilized small data cells to reduce jitter (delay variance, in this case) in the multiplexing of data streams. Reduction of jitter (and also end-to-end round-trip delays) is particularly important when carrying voice traffic, because the conversion of digitized voice into an analogue audio signal is an inherently real-time process, and to do a good job, the decoder (codec) that does this needs an evenly spaced (in time) stream of data items. If the next data item is not available when it is needed, the codec has no choice but to produce silence or guess — and if the data is late, it is useless, because the time period when it should have been converted to a signal has already passed.
At the time of the design of ATM, 155 Mbit/s Synchronous Digital Hierarchy (SDH) with 135 Mbit/s payload was considered a fast optical network link, and many Plesiochronous Digital Hierarchy (PDH) links in the digital network were considerably slower, ranging from 1.544 to 45 Mbit/s in the USA, and 2 to 34 Mbit/s in Europe.
At this rate, a typical full-length 1500 byte (12000-bit) data packet would take 77.42 µs to transmit. In a lower-speed link, such as a 1.544 Mbit/s T1 line, a 1500 byte packet would take up to 7.8 milliseconds.
A queuing delay induced by several such data packets might exceed the figure of 7.8 ms several times over, in addition to any packet generation delay in the shorter speech packet. This was clearly unacceptable for speech traffic, which needs to have low jitter in the data stream being fed into the codec if it is to produce good-quality sound. A packet voice system can produce this low jitter in a number of ways:
  • Have a playback buffer between the network and the codec, one large enough to tide the codec over almost all the jitter in the data. This allows smoothing out the jitter, but the delay introduced by passage through the buffer would require echo cancellers even in local networks; this was considered too expensive at the time. Also, it would have increased the delay across the channel, and conversation is difficult over high-delay channels.
  • Build a system that can inherently provide low jitter (and minimal overall delay) to traffic that needs it.
  • Operate on a 1:1 user basis (i.e., a dedicated pipe).
The design of ATM aimed for a low-jitter network interface. However, "cells" were introduced into the design to provide short queuing delays while continuing to support datagram traffic. ATM broke up all packets, data, and voice streams into 48-byte chunks, adding a 5-byte routing header to each one so that they could be reassembled later. The choice of 48 bytes was political rather than technical.[4] When the CCITT (now ITU-T) was standardizing ATM, parties from the United States wanted a 64-byte payload because this was felt to be a good compromise in larger payloads optimized for data transmission and shorter payloads optimized for real-time applications like voice; parties from Europe wanted 32-byte payloads because the small size (and therefore short transmission times) simplify voice applications with respect to echo cancellation. Most of the European parties eventually came around to the arguments made by the Americans, but France and a few others held out for a shorter cell length. With 32 bytes, France would have been able to implement an ATM-based voice network with calls from one end of France to the other requiring no echo cancellation. 48 bytes (plus 5 header bytes = 53) was chosen as a compromise between the two sides. 5-byte headers were chosen because it was thought that 10% of the payload was the maximum price to pay for routing information.[3] ATM multiplexed these 53-byte cells instead of packets which reduced worst-case cell contention jitter by a factor of almost 30, reducing the need for echo cancellers.

2012年3月7日星期三

关于windows wifi API的一段说明

If you are starting the development of some software that must manage WiFi connections and settings in Windows, you will be faced with the following problem. There are two versions of Windows that have API for WiFi networks management: Windows XP Service Pack 2 (or SP3) and Windows Vista, and both versions use absolutely different APIs for wireless network management.

  • Windows XP SP2/SP3
    - uses the "Wireless Zero Configuration" (WZC) API. This API is almost undocumented and there aren't any examples how to use it, although this API can perform all necessary operations with WiFi connections and Windows XP SP2/SP3 is the most popular version of Windows at present.
  • Windows Vista and Windows 7
    - uses the "Native WiFi" API. This is a new API that allows you to manage WiFi networks, this API is simpler and more documented, although there is only one example how to use it. You can find this example for the C++ language in the Vista SDK.
There is a patch from Microsoft that allows you to use part of the "Native WiFi" API in Windows XP SP2, though it means that your software must download and install this patch. Unfortunately, we have tried using the "Native WiFi" API for XP in our projects and we have found out that it does not work properly in some cases. It returns some data fields incorrectly and does not set some of them at all. After studying it in detail, we have discovered that the "Native WiFi" API for Windows XP is only a wrapper for the WZC API and it is much better to use the WZC API directly.

--------------------------------------


参考:

http://www.codeproject.com/Articles/19341/Wifi-scanner-custom-MFC-controls

http://openwps2.googlecode.com/svn-history/r73/trunk/WM_client_cpp/WifiPeek.cpp

http://www.codeproject.com/Articles/24756/How-to-query-miniport-driver-information-802-11-OI

Linux traffic control参考链接

http://blog.edseek.com/~jasonb/articles/traffic_shaping/introduction.html

http://tldp.org/HOWTO/Traffic-Control-HOWTO/index.html

http://www.docum.org/docum.org/

http://opalsoft.net/qos/

2012年3月1日星期四

Policing

Policing就是超出限速后将包直接丢弃,它通常是和filter结合在一起用。filter可以对包采取多种措施:

 - ok or pass     - 通常用于暂时禁用掉某个filter

 - continue         - 找不到匹配的filter,继续找其他的匹配

 - drop or shot   - 丢弃

 - reclassify        - 重新标记为Best Effort,默认的action

 如果qdisc没有实现policing,那么drop和reclassify会被当做continue,即不被处理。

有两种方式来做police:

1. kernel estimator,内核的estimator来统计Exponential Weighted Moving Average平滑后的速率(40ms统计一次,每秒有25次统计,然后再平滑),用来避免burst流量的影响,如果超出,就采取特定的措施,默认是reclassify。这种方式只需要一个参数avrate。

2. 使用token bucket filter。这种和tc-tbf一样,只是数据不会缓存,所以没有"limit/latency"的参数,可用的参数如下:

  - burst/buffer/maxburst,桶的容量

  - mtu/minburst, 第二个burst桶的容量,如果设置的太小,包有可能会过不去。

  - mpu,minium packet usage,每个包不管大小多大,都需要消耗token,这个值指定了一个包需
    要消耗的最小token量(字节)。

  - rate, 第一个桶token注入的速率

例子:

1) 限制icmp的流量为2kbit:

tc filter add dev $DEV parent ffff: protocol ip prio 20 u32 match ip protocol 1 0xff police rate 2kbit buffer 10k drop flowid :1


2)限制包大小不超过84byte:

tc filter add dev $DEV parent ffff: protocol ip prio 20 u32 match ip tos 0 0xff police mtu 84 drop flowid :1

3)丢弃所有的icmp包:

tc filter add dev $DEV parent ffff: protocol ip prio 20 u32 match ip protocol 1 0xff police mtu 1 drop flowid :1

模拟国内某些小区adsl的带宽限制

这类网络在速率超出带宽限制后就直接丢包,不会缓存数据,即采用的是police而不是shape。

要用linux的流量控制模拟这种情况,需要在ingress上采用流量控制,这里使用linux的eth0做包转发

tc qdisc add dev eth0 ingress

可以用tc qdisc show dev eth0来查看,可以看到id为"ffff:"的qdisc就是ingress对应的qdisc的id:

qdisc ingress ffff: parent ffff:ffff1 ------------

接下来添加一条过滤规则,并设置限速策略,将目标地址为64.104.177.71的包过滤出来,如果要匹配任意地址,可以使用0.0.0.0/0

tc filter add dev eth0 parent ffff: protocol ip prio 20 u32 match ip dst 64.104.177.71 police rate 800kbit burst 10k drop flowid :1


这里flowid :1是比较费解的,很少有提及,看到一个比较合理的解释是:

“ As fas as I know,this qdisc is a dummy one, and flowid is just used with :1 because the traffic have to be redirected to something.”

也就是说过滤出来被drop掉的数据会被重定向到一个dummy的qdisc?

要查看filter是否生效可以用,但这里只能看到egress接口上面的

tc filter show dev eth0


对于ingress的filter,需要使用

tc filter show parent ffff: dev eth0

2012年2月29日星期三

HTB的原理

定义:

1. Class有 AR(assured rate),CR(ceil rate),priority,level和quantum Q。Class可以有parent。class的当前流量是R,对于inner class(非叶子节点),它的R是所有叶子节点的R总和。

2. Leaf是没有孩子的class,只有Leaf才有包队列。

3. Level是class在树形结构所在的层次,leaves的level是0,root是LEAVEL_COUNT-1,每个inner class的level比父节点的level要少1。

4. class的Mode可以根据R, AR, CR计算出来:
 
     -  Red: R > CR,当前流量超过最高的流量限制
     -  Yellow:  R <= CR and R > AR,当前 流量比保证的流量限制要高,但比最高的流量限制要小。
     - Green:  R <= AR

5. D(c)是所有的叶子节点,这些叶子节点都需要从c来借流量(对应上面的Yellow Mode)。

链路分享的目标:

c是class, p是parent


Rc = min(CRc, ARc + Bc)        [eq1]


Bc是指从父节点借的流量,如果没有父节点,那Bc就是0;如果有p的其他叶子节点需要借流量,并且优先级要比当前class的优先级高(数值低),那么当前的class就不应该被服务,Bc也是0;如果轮到当前的class,那么综合和当前class同一优先级的class,以这些class的Q(quantum)为权重来分配剩余的流量Rp。


       Qc Rp
Bc = -----------------------------  iff min[Pi over D(p)]>=Pc  [eq2]
     sum[Qi over D(p) where Pi=Pc]

Bc = 0   otherwise      [eq3]
 
 
 

修改wifi信号以避免干扰

家用的无线网络基于802.11b或802.11g标准,信号传输的频率范围是2.4G Hz,家用的很多其它设备,比如无绳电话,微波炉等,都可能使用同样的频率范围,这些都能够影响wifi网络,造成传输速率的降低和网络连接的中断。邻居家的wifi信号也同样可能会影响你家的。

2.4G Hz的频率范围被划分为很多band(channel),类似于电视的频道(channel)。在大多数国家,wifi设备提供了一些可选择的channel,合理的选择channel能避免干扰的影响。美国的设备有11个channel,channel 1使用最低的频率,后面的channel的频率依次递增,默认的channel是6,离得越远,干扰越小。

2012年2月28日星期二

IMQ和IFB

IMQ - Intermediate Queueing Device

作用:

1. Ingress的整形。linux只能在egress做整形。

2. 同时对多个接口做整形。qdiscs只能附加到一个设备上,有时需要设置全局的限制。

IFB - Intermediate Functional Block Device,作为IMQ的替代品,实现更简单,只有200行代码。可以将其他接口的流量重定向到这个接口,来做同一的整形控制,并且能支持(Ingress)下行流量的整形。

如果板卡出现了莫名其妙的错误,你可能需要关注中断资源哦[转]

        因为用的Asterisk板卡太多,电脑的升级换代速度又如此之快的原因吧,经常遇到一些稀奇古怪的问题。中断资源(IRQ)问题是其中一个重要的值得关注的问题。
1、什么是中断IRQ(温习一下计算机原理课程)
        IRQ 为 Interrupt ReQuest的缩写,中文译为中断请求。因为计算机中每个组成组件都会拥有一个独立的IRQ,除了使用PCI总线的PCI卡之外,每一组件都会单独占用 一个 IRQ,且不能重复使用。 注意,这段话说明,PCI总线的PCI卡喜欢分享中断,而不是独占——这就是隐患所在。
        中断的工作原理是:由于在计算机运行中,CPU是持续处于忙碌状态,而当硬件接口设备开始或结束收发信息,需要CPU处理信息运算时,便会透过IRQ对 CPU送出中断请求讯号,让CPU储存正在进行的工作,然后暂停手边的工作,先行处理周边硬件提出的需求,这便是中断请求的作用。
   
在 每个系统中会有两颗芯片来提供16个IRQ(资源有限啊),其中大多的IRQ都有固定的编排,比如 IRQ 0固定为系统定时器,IRQ 1则是键盘,IRQ3和IRQ4是给串口用。因为每一个IRQ只能让一种设备使用,而IRQ数目又十分有限,若计算机安装很多的配件,IRQ势必就会不敷 使用,所以可能会发生两个设备共占同一个IRQ的现象,此时也就会出现IRQ冲突问题,造成该设备无法使用。
   
最简单的解决方法就是到操作系统的硬件设备管理器中去手动调整IRQ的分配,或是在BIOS中作调整。如果是IRQ不敷使用的情形,可以利用其它的方式来解决此一窘境,像是PCI总线可以共享一个IRQ,所以基本上可以采增加PCI插卡的方式,就不会被IRQ 所限制。

2、Asterisk板卡的中断原理
        Asterisk卡是每秒钟发生1000次中断的,每片卡每1ms申请一次中断。(现在新的卡已经可以调中断次数了)。其他语音卡也是类似的,中断次数可能各家不一样。
        如果发生的中断次数少于1000次,就是Asterisk中断丢失.。你可以通过用'zttool',查看卡是否发生了中断丢失。
        虽然IRQ缺失不会导致报警,但是发生IRQ缺失会出现一些症状,会导致Asterisk不同的问题发生:比如出现很差的声音质量或者PRI错误,DTMF检测不能正常工作等。

3、为什么我的卡有IRQ中断丢失?
     
        导致IRQ丢失的一些常见的原因如下:
                -运行 X window system
                -共用了IRQs
                -没有硬盘驱动器的DMA
                -硬盘驱动器的DMA太高(达到udma3)
                -运行串行终端或帧缓冲器

        对于IRQs共用情况,可以用下面的命令来检查:
                  cat /proc/interrupts CPU0
引用
      
      
      
      
      
      
0  10756672XT-PIC timer
2  0       XT-PIC cascade
5  10812879XT-PIC uhci_hcd, uhci_hcd, wctdm
10 226219  XT-PIC t1xxp, CS46XX
11 1550046 XT-PIC eth0, nvidia
12 387234  XT-PIC i8042
14 32641   XT-PIC ide0
15 18      XT-PIC ide1
NMI0      
LOC10757616
ERR40481  
MIS0      

         在这里您可以看到T100P卡和声卡共用了IRQ,TDM400P卡和USB controller共用了中断。这样很有可能会出问题。如果你不用USB设备倒是没什么。但是最好是disable USB或者让有自己单独的IRQ。

4、怎样解决Asterisk语音板卡的IRQ中断丢失问题
        有以下几种方法让板卡有自己的IRQ:
                -Turn on APIC
                -Tweak BIOS settings
                -Try a different PCI slot
                -Use setpci
        解决中断冲突的常见方法有:
        1、调整硬件,能不用的尽量不接到电脑上。常用来解决中断冲突造成的死机和较难排除的IRQ冲突。这个办法就是在主板BIOS默认的IRQ资源分配下,通过调整板卡(声卡、Modem、网卡、电视卡、显卡等)于插槽的安装位置来避开IRQ冲突。
        2、在BIOS里做设置,对于某些不太严重的冲突,可以通过调整BIOS设置的软着陆办法,通过调整BIOS中的“PNP/PCIConfiguration”设置项,重新分配IRQ资源,以避开IRQ冲突。

这里有一个英文的:

Verify that your Digium hardware is not sharing an IRQ on your
system. You can accomplish this by running "cat /proc/interrupts". Do
not solely rely on "cat /proc/interrupts" to determine whether your
Digium hardware is sharing an IRQ on your system. Make sure your Digium
hardware is on its own IRQ by itself and that it is taking interrupts.
You can determine whether it is taking interrupts from the 2nd column of
output from "cat /proc/interrupts". This should be something other
than zero. You will also need to verify that your Digium hardware is
not sharing an IRQ by examining the output after running"lspci -v" and
"lspci -vb". Using lspci is the best way to determine whether or not
your Digium hardware is sharing an IRQ on your system. Please verify
that all Digium hardware is on its very own IRQ by itself. You may need
to disable unnecessary hardware on your machine such as sound
controllers, USB controllers, extra ethernet controllers, firewire,
parallel ports, and/or serial ports. You should try moving and swapping
the Digium card to different PCI slots in order to get it on it's own IRQ.
Some BIOS's will allow you to specify an IRQ for each PCI slot and/or
onboard devices.

If you are running an IDE hard drive please verify that you are using
DMA mode with a UDMA setting of no lower than 2 or higher than 3. UDMA
mode 2 is ATA33. UDMA mode 3 is ATA44. This can be done using hdparm.
Digium suggests using "hdparm -d 1 -X udma2 -c 3 /dev/IDE Device". You
can check the status using "hdparm /dev/IDE Device" and "hdparm -i
/dev/IDE Device". If you make modifications to your IDE hard drive
settings they will only be kept until you reboot. You will need to add
the hdparm command you executed to one of your distribution's startup
scripts. This way the IDE hard drive settings will be updated on each
reboot.

You can check whether or not your Digium hardware on your system is
experiencing IRQ misses by using the zttest application which should be
located in yourzaptel source directory. Do not solely rely on zttest to
determine whether you are having IRQ misses with your Digium hardware on
your system. Optimally, we are looking for output of 100% from zttest.
Digium cards will function properly as long as they do not report back less
than 99.98%. Some people have reported no apparent problems with output
as low as 99.975%, while others will have many apparent problems with an
output as low 99.975%. You are almost guaranteed to have many apparent
problems with an output lower than 99.975%. Digium strongly suggest doing
everything possible in order to obtain at least 99.98% output from
zttest. I would watch the output over a 5 minutes period to check for
spikes on intervals. You may also look for IRQ misses using the zttool
application. Do not solely rely on zttool to determine whether you are
having IRQ misses with your Digium hardware on your system. This
application should be built while compiling zaptel. zttool requires the
libnewt development package to be installed on your system in order to
compile properly.

IRQ misses with your Digium hardware can be due to I/O problems on your
system. You may test if you are having I/O problems on your system by
running "hdparm -t /dev/Hard Drive Device". This will causes massive
amounts of I/O on your system. The symptoms of an I/O problem on your
system could be cracklingand/or static on the line while running "hdparm
-t /dev/Hard Drive Device". If you are having an I/O problem on your
system and run this command it could result in dropped calls
temporarily. If you are experiencing those symptoms while running
"hdparm -t /dev/Hard Drive Device" it is likely that you havean I/O
problem on your system. We would suggest using an IDE harddrive rather
than SCSI or SATA in order to configure your hard drive to UDMA2.
Configuring a SCSI or SATA hard drive to UDMA2 is not possible. This is
only possible on an IDE hard drive. Do not solely rely on "hdparm -t
/dev/Hard Drive Device" to determine whether or not you have an I/O
problem on your system.

        Please ensure that you are not running X-Windows, frame-buffer, or
serial console, as these will cause problems with our hardware. You can
disable frame-buffer by supplying the "vga=normal" option to your kernel
at boot time. Frame-buffer may start your console with a high
resolution and a logo that is alongthe top of the screen.

        如果还有中断丢失问题,你可以设置启动kernel的时候设置参数为 "acpi=off" 和/或者"noapic" ,这样可以禁用ACPI(电源管理)。这个也是常见的中断共享来源之一。

        如果你的系统支持超线程(Hyper-Threading),你可以尝试在BIOS里面关掉它,看看是否会对中断冲突问题有改善。

http://www.51asterisk.com/read.php?tid=506&fpage=2

Asterisk如何判断模拟卡线路上的占线忙音和拆线音(挂机)[转]

       FXO端口(外线,O口,中继线,模拟线,电话线,红模块)用在非北美地区的模拟线路上时,通常用的是loopstart信令,靠识别来自FXS的有特定的频率和特殊的通断比的规律声音(信号音)来判断线路的状态(使用中/已挂机/用户闲)。
        由于包括中国在内的很多发展中国家的国情现状,很多地区的信号音是非标准的。下面我们以中国为例,介绍Asterisk如何判断模拟卡线路上的状态。
1. 标准的信号音
        在中国,规范的忙音信号应该是(0.35秒通,0.35秒断,声音频率是450kz)。Asterisk在indications.conf对cn(中国)的定义就是如此:
引用
[general]
country=cn
....
[cn]
ringcadence = 1000,4000
dial = 450                                                  ;拨号音
busy = 450/350,0/350                                ;中国忙音标准
ring = 450/1000,0/4000                              ;振铃音
congestion = 450/700,0/700                       ;拥塞音
callwaiting = 450/400,0/4000                       ;呼入等待音
dialrecall = 450
record = 950/400,0/10000
info = 450/100,0/100,450/100,0/100,450/100,0/100,450/400,0/400
stutter = 450+425

        拨号音:(450Hz,-10±3dBm0,连续)——“嗡…”的连续音。
        忙音:(450Hz,-10±3dBm0,0.35s on/0.35s off)——“嘟,嘟,嘟…”短促音(响0.35秒,断0.35秒)。
        拥塞音:(450Hz,-10±3dBm0、0.7s on/0.7s off)——这是一种“嘟,嘟…”的短音(响0.7秒,音隔0.7秒)。拥塞音有点像忙音,但比忙音声音要长,它表示程控交换机因某种原因机线拥塞不通。
        呼 入等待音:(450Hz,-20±3dBm0、0.4s on/4.0s off)——在用户登记了“呼叫等待”服务项目后,如果该用户正与对方通话时,又有第三者呼叫该用用,则该用户在受话器中会听到一种微弱的信号音,这种信 号是“嘟…”的短促音(响0.4秒,音隔0.4秒,再响0.4秒)。它表示有第三者在呼叫,提醒该用户是否要与第三者通话。
        特 种拨号音: (450Hz,-10±3dBm0,0.4s on/0.04s off)这是一种“嘟,嘟…”的一短一长的声音,当用户的电话中登记了某种程控电话服务项目后,摘机听到的拨号音就是这种特种拨号音,用以提醒该用户。这 种拨号音不妨碍该用户打电话,只要在规定产时间(5秒)内拨号即可。
        二次拨号音:(400Hz,-10±3dBm0、连续)
        回铃音:(450Hz,-10±3dBm0,1.0s on/4.0s off)——“嘟,嘟…”的断续音(响1秒,断4秒)表示用户拨叫的对方电话已接通,正在振铃。  
        空 号音:(450Hz,-10±3dBm0、0.1s on/0.1s off/0.1s on/0.1s off/0.1s on/0.1s off/0.4s on/0.4s off)--“嘟、嘟、嘟-”的450赫的三短一长音(短音为0.1秒,间断0.1秒,长音为0.4秒)
        三方通话提醒音:(950Hz,-20±3dBm0、0.4s on/10.0s off)
        催挂音:(950HZ 0.4dB)——当用户用完电话,没有挂机或话机手柄没有放好时,程控电话局会发出一种由小逐渐变大的连续音(950HZ),提醒该用户把话机挂好。
        长 途通知音:(450Hz,-10±3dBm0,0.2s on/0.2s off/0.2s on/0.6s off)——当用户在市内电话通话过程中,又听到“嘟,嘟”声,跟着一小段间歇,又再“嘟,嘟”,这样的短音(响0.2秒,断0.2秒,音隙0.6秒)就 是“长途电话通知音”,告诉用户有人工长途电话要和您通话,请尽快结束市内通话,准备接听长途电话。这种长途电话通知音随着我国长途电话自动化的普及也越 来越少了。

2. 非标准信号音的处理
  事实上,除了一些大城市的固网电信公司交换机能够提供标准信号音外,由于中国电信经过很长时间的七国八制的盲目发展阶段,很多地方的信号音是不标准的。
        如果电信公司给你的忙音信号根本就是不标准的,Asterisk怎么可能识别呢?必然出现无法正确判断拆线的状况。
        这 种情况下,就得通过ztmonitor录音后,判别它通断比,然后将这些数值填入zapata.conf的busypattern 中,然后重启asterisk服务器(例如beep持续600号码,静音400毫秒,那么busypattern=600,400)
  在中 国,Asterisk的zapata.conf需要启用busydetect=yes,以及busycount=6可以解决大多数忙音识别和无法拆线的问 题(基于loopstart),zapata.conf(或zapata-channels.conf)设置如下:
引用
busydetect=yes
busycount=6                          ;设置的值过小会引起通话中中断的故障
....................
loadzone = cn
defaultzone = cn

        提 示:不要盲目按照某些技术帖子所说的,随便增加busypattern这个参数。除非你明确知道这么作的原因。没有这个参数,Asterisk接受任何有 规律的断通信号在busycount规定的次数内判别为忙音。如果busy tone的通断间隔不相等(如前文提到的beep 600毫秒,静默400毫秒),才需要手工设置.
  如果上述设置在你的机器上不生效,请检查线路质量,检测是否有回声,有的时候线路的杂音会干扰到Asterisk的忙音识别。

3. 极性反转信号(反极信号)
        如果是话务量比较密集的应用或对计费数据比较敏感的环境,建议去电信申请反极信号(反极信号就是极性反转信号,跟kewl start不是一回事)。同时在zapata.conf中增加:
引用
hanguponpolarityswitch=yes ;拆线
answeronpolarityswitch=yes ;对端应答(用于计费)

        这两个设置不要和busydetect=yes或callprogress=yes同时使用。

4. 小技巧: 如何确定自己的线路是否支持kewlstart
        将 一个支持拨号盘高亮的(不需要外接电源,直接从市话取电)的普通模拟电话机连接到PSTN线路上,拨通你的手机,接听手机,然后手机挂机。如果那部模拟电 话机在远端(手机)挂线后拨号盘灯熄灭(drop battery),那么这条线路是支持kewlstart的,不需设置busyXXX和callprogress。
  不要把callprogress和busyxxx属性混用,这是两种不同的工作方式.目前默认工作方式的callprogress仅对北美生效。

Asterisk模拟卡的馈电、铃流[转]

1. 馈电

        俗称供电。馈电方式有电压馈电和电流馈电两种。所有连接在交换系统的终端,都是由交换机向其供电。
        用户挂机状态下,程控交换机的馈电电压在直流48V,电流应该在5微安左右。
        通话时,馈电电流在20毫安—50豪安之间,电压下降到7-10V。
        而小型集团电话交换机(用户小交)的馈电电压在30V左右,馈电电流在20毫安—30毫安之间,这就是为什么程控交换机比集团电话传输距离更远的原因之一。
        而 Asterisk语音卡的FXS端口一般都采用计算机内置的12V直流电源作为馈电电压,馈电电流在20毫安之内,这也就是Asterisk系统无法支持 远距离传输的原因。无法支持远距离传输,也就不可能支持超大型厂矿企业的上千线电话分机的应用了(符合SMB的定位)。

2. 振铃

        振 铃电压较高,国内交换机一般为交流90V左右,频率为16-25Hz。通常采用继电器来控制铃流接点。振铃是由交换机系统来控制,当需要振铃时,发出控制 信号,是继电器闭合,振铃电路发出铃流信号至用户。当用户摘机时,摘机信号由振铃监视电路检测,立即切断振铃,提供馈电电流(通常叫做自动截铃)。有些集 团电话和PBX的这部分功能由高压电子器件实现,取消掉了继电器。
        Asterisk模拟语音卡的S口模块能够提供的馈电和铃流电压都比较低。

3. 常见问题
        如果一个正常运行的系统突然发现无法对电话机振铃或电话机摘机起来没有拨号音,可能是:
        . Asterisk模拟接口卡的电源接口松了,重新接一下。
        . FXS接口模块(绿模块)坏了,需要更换。

http://www.51asterisk.com/read.php?tid=634 

Asterisk模拟卡的FXO(外线)和FXS(内线)端口详解 [转]

1. 模拟卡接口
        模拟卡端口只有FXO(外线)和FXS(内线)两种类型,有时,也把FXO叫做模拟中继接口或外线模块,把FXS叫做坐席接口或坐席模块或内线模块。
        FXO-Foreign Exchange Office,以下简称O口。
        FXS-Foreign Exchange Station,以下简称S口。
  两者的差别就是S口提供电压(实现馈电和铃流),而O口不提供。家里用的普通电话机就是一个典型的FXO设备。
  在现实世界中,S口和O口总是成对出现的.由S口向O口馈电(提供电压),振铃;FXO向FXS传送号码(DTMF/FSK).所以对接时会出现fxs侧的用户需要首先呼叫到fxo,再二次拨号呼叫到被叫侧,而fxo侧用户可以一次直接呼叫被叫用户(一次拨号)。

2. Asterisk模拟卡接口
  Asterisk模拟卡无论4线,8线,12线,16线,24线或其他规格,其端口也只有S和O两种类型。也有人根据直观颜色,把FXO叫做红模块,FXS叫做绿模块,因为大部分Asterisk板卡厂家的FXO模块都是红色外观,而FSX模块都是绿色外观。
        在Asterisk中,FXO接口接受的是fxs信令和FXS提供给fxo信令.所以你在zapata中看到fxsXX(ls,gs,ks) 这个端口是FXO接口,如果是fxoXX(ls,gs,ks) 这个端口是FXS接口.
  FXO用于连接PSTN(因为PSTN测其实是一个S口,向Asterisk的FXO接口馈电)
  FXS用于连接普通电话机,因为Asterisk通过FXS接口向电话机(还记得吗?我们刚刚说过普通电话机是一个FXO设备)提供馈电。这也是为什么Asterisk模拟卡上如果有FXS模块的需要外接电源的原因。因为只有外接电源才让FXS能向外提供馈电和铃流。
  倘若Asterisk系统位于企业用户小交交换机(PBX)的后面,那么Asterisk的FXO接口和PBX的模拟分机口相连,asterisk的FXS接口和PBX的模拟中继端口相连。


http://www.51asterisk.com/read.php?tid=633

Asterisk模拟线FXO的主叫号码识别(来电显示)[转]


       CID (CallerID,CLID,主叫号码,来电显示)是在实际使用中常遇到的另外一个常见问题,主叫号码格式分为FSK(美规)或DTMF方式。主叫号码可能会在第一声振铃之前送过来,也可能在第一声振铃之后,第二声振铃之前发送过来。

1. 如何确定CID的制式
        最简单是拿原来可以支持来显的电话机来看(必须是有时间显示的电话机)。
        1、先把机器的时间调乱.(随便调,但月份一定调)
        2、然后用自己的手机打进去,电话响5声后挂掉,不要接。
        3、然后看时间自动改过来了没.
        如果是改过来了(年份不改不要紧,但月份一定要),那证明是FSK制式。如果没改过来那就是DTMF制式。

2. 区分FSK的制式
        区分了fsk之后,如果在第一声之前,就显示了号码,那么就是欧式的FSK;如果在第一声和第二声之间才显示来电号码,那么就是美式的FSK。

3. 主叫号码的制式与运营商和地区的关系
        主叫号码的制式与运营商(是南方电信还是北方网通,联通,或者是铁通)关系不大。即便是同一个城市的同一个运营商,也可能提供两种制式的主叫号码,这主要取决于电信交换机。

4. Asterisk对主叫号码制式的支持
        Asterisk 是美国人做的,所以对FSK制式的支持相对比较好,但是如果遇上DTMF制式的主叫号码,确实挺麻烦的。解决办法有两个,一个是花50块钱买个转换器(就 是那个DTMF转FSK的)或修改驱动程序来解决。可以参照OPENVOX的方法,修改两个文件并重新编译zaptel驱动,将OPENVOX的 wctdm.c覆盖掉,opvxa1200.c里面的……。
        在后面的文章中,我们会专门针对DTMF制式的主叫号码识别做专文介绍。

5. 小知识:什么是FSK
        FSK(Frequency- shift keying):频移键控,是信息传输中使用得较早的一种调制方式,它的主要优点是:实现起来较容易,抗噪声与抗衰减的性能较好,因此在低速数据传输中得 到了广泛的应用。以前有一个叫做固网短信的业务,就是利用了FSK技术来传递短信息的。
        FSK也有很多标准,中国、美国、澳大利亚采用的bellcore标准(贝尔202 / V.23)。  

loop start,kewl start,grand start[转]


模拟线路信令模式loop start,kewl start,grand start

        模拟线路信令模式有loop start,Kewl start,grand start等三种。
  这三个术语很专业了。普通用户不需要了解很多。
        grand start是需要专门申请的,一般用于中继线(它的好处就在于可以避免进线和出线的碰撞,提高线路使用率),在Asterisk中用不到,如果你不知道它是什么,忘了它吧,你不会用到它的。
        而 普通的电话线路一般是loop start的,Asterisk推荐的kewlstart也是一种loop start,只不过它能识别supervisor disconnect信号(就是远端拆线后在发送忙音之前,发送这个信号。所以如果你的局端提供的是kewlstart信号,Asterisk默认的配置 可以很正确的识别远端拆线,这也就是为什么默认的zapata.conf中不启用busydetect的原因)。
        在中国大陆,主要采用的是loop start,而北美采用的是kewlstart。
   所以当你正确安装了卡板和驱动,但用默认的fxsks信令,拨号到pstn得到"all circuit busy now"的提示语时,尝试将zaptel.conf和zapata.conf中默认的fxsks改为fxsls (修改完毕后需要重启机器而不是单纯重启asterisk)。

        在北美,模拟卡应用很少出现问题,就是因为信令是 kewl start,而其他地区因为信令是loopstart,完全靠模拟信号音而不是相对准确的电压来判断摘挂机,所以很容易出现问题。所以如果遇到模拟线路的 信令问题是,最好向电信公司申请极性反转信号……  

原文地址:http://www.51asterisk.com/read.php?tid=635

2012年2月26日星期日

tc-sfq

Stochastic Fairness Queueing (SFQ) 是公平队列算法的一个简单实现,它准确度不高,但计算开销也比较小,也能够保证公平。

SFQ为每一个会话(TCP或UDP)提供一个FIFO的队列(这里的会话通常是[source address, destination address, source port ]),然后每个队列采用round robin的方式去发送数据。实际的实现并不会为每个会话提供一个队列,而是采用hash算法将流量分配到有限的几个队列中,这时,多个会话可能会分到同一个queue中,降低各种发包的机会(减少了速率),为了避免这种情况,SFQ会动态的调整hash算法,减少出现这种冲突的时间,在调整过程中,可能会出现包乱序的情况。

SFQ只进行调度,并不进行流量整形。并且需要保证拥塞的队列是在当前配置策略的机器上,即如果拥塞地方在其他的链路则没有效果。SFQ通常和其他的classful的qdisc如HTB一起使用。

参数:

perturb - hash算法重新调整的时间间隔,建议值10秒。

quantum - round robin每一轮可以发送的字节数,不能比MTU小。

limit - SFQ队列缓存的包个数,超过了就开始丢弃,默认128个包。

例子:


# tc qdisc add dev ppp0 root sfq perturb 10
# tc -s -d qdisc ls
qdisc sfq 800c: dev ppp0 quantum 1514b limit 128p flows 128/1024 perturb 10sec 
 Sent 4812 bytes 62 pkts (dropped 0, overlimits 0) 

800c是自动指定的handle id,队列长度限制为128个包

tc-pfifo,tc-bfifo和pfifo_fast

这三种都是classless的Queuing Discipline。classless的qdisc可以用来对特定的接口进行总的限制,不能划分子类,但可以应用在子类上。

Linux默认的qdisc是pfifo_fast,这种fifo有三个队列,FIFO0,FIFO1,FIFO2,对应的优先级分别从高到低,分为3个band,0最先调度,0处理完后,其次是1,然后是2,优先级对应于包内的ToS字段,那些需要最小时延的包会被放到band0中。

ToS和band之间的映射关系如下:


TOS     Bits  Means                    Linux Priority    Band
------------------------------------------------------------
0x0     0     Normal Service           0 Best Effort     1
0x2     1     Minimize Monetary Cost   1 Filler          2
0x4     2     Maximize Reliability     0 Best Effort     1
0x6     3     mmc+mr                   0 Best Effort     1
0x8     4     Maximize Throughput      2 Bulk            2
0xa     5     mmc+mt                   2 Bulk            2
0xc     6     mr+mt                    2 Bulk            2
0xe     7     mmc+mr+mt                2 Bulk            2
0x10    8     Minimize Delay           6 Interactive     0
0x12    9     mmc+md                   6 Interactive     0
0x14    10    mr+md                    6 Interactive     0
0x16    11    mmc+mr+md                6 Interactive     0
0x18    12    mt+md                    4 Int. Bulk       1
0x1a    13    mmc+mt+md                4 Int. Bulk       1
0x1c    14    mr+mt+md                 4 Int. Bulk       1
0x1e    15    mmc+mr+mt+md             4 Int. Bulk       1


包结构,TOS字段4bit,另外后面还有1bit,总是0:

   0     1     2     3     4     5     6     7
+-----+-----+-----+-----+-----+-----+-----+-----+
|                 |                       |     |
|   PRECEDENCE    |          TOS          | MBZ |
|                 |                       |     |
+-----+-----+-----+-----+-----+-----+-----+-----+


4bit ToS字段:

Binary Decimcal  Meaning
-----------------------------------------
1000   8         Minimize delay (md)
0100   4         Maximize throughput (mt)
0010   2         Maximize reliability (mr)
0001   1         Minimize monetary cost (mmc)
0000   0         Normal Service
 
 
pfifo_fast的队列长度不能通过tc命令设置,只能通过ifconfig设置整个接口的队列(见下面的说明) 




另外还有两种先进先出的排队策略,一种是pfifo,按包的个数限制队列长度,另一种是bfifo,按字节数来限制队列长度

tc qdisc ... add pfifo [ limit packets ]

tc qdisc ... add bfifo [limit bytes]

使用这个来代替默认的qdisc的原因是,他们有统计信息。

参数: limit,默认pfifo的值是txqueuelen,这个可以通过ifconfig或ip命令来指定,txqueuelen是设备中的传输队列,通常在慢速连接上会设置比较小的值,防止突发的流量导致接口这里出现长时间的拥塞,造成时延增大,影响交互应用;默认bfifo的值是txqueueulen * MTU。

要设置txqueuelen,可以使用ifconfig:

ifconfig eth0 txqueuelen 10

可以使用下面的命令来查看接口的网络统计信息:


# tc -s qdisc ls dev eth0
qdisc pfifo 8001: dev eth0 limit 100p
 Sent 45894 bytes 681 pkts (dropped 0, overlimits 0)

2012年2月21日星期二

tc-htb限速

HTB - Hierarchy Token Bucket,从字面意义上上,这个是分层次的,HTB的规则本质上是一个树形结构。HTB可以用来在一个物理链路上虚拟多个链路,并能合理的利用空闲带宽,限速的原理和TBF是一样的。HTB比CBQ更加灵活,但是CPU开销也更大,通常高速的链路会使用CBQ,一般而言HTB使用的更加广泛,比HTB更加强大的是HSFC,原理一样,但是有更多的功能。

如果将HTB的分层结构看作树,那么每个节点就被称为一个class,每个class可以设置一个qdisc,默认的是tc-pfifo。 另外HTB还可以设置一些过滤器,通过这些过滤器可以将到来的包分发到指定的class上。这里过滤器通常挂载在root节点(egress接口),但匹配只能匹配叶子节点。

HTB是属于classful的qdisc,这类classful的qdisc可以使用filter来将包指定到特定的队列。classful的qdisc的子class只能是同类型的classful qdisc,或者是classless的qdisc,即HTB的子class只能用HTB或其他的classless的qdisc,如pfifo或者


tc qdisc ... dev dev ( parent classid | root) [ handle major: ] htb [ default minor-id ]



 Qdisc的参数:  

parent major:minor 或者 root。 一个qdisc是根节点就是root,否则其他的情况指定parent。其中major:minor是class的handle id,每个class都要指定一个id用于标识。

handle major: ,这个语法有点奇怪,是可选的,如果qdisc下面还要分类(多个class),则需要指定这个hanlde。对于root,通常是"1:"。

注意:对于tc命令中的qdiscs和classes,标识handle(classid)的语法都是x:y,其中x是一个整数用来标识一个qdisc,y是一个整数,用来标识属于该qdisc的class。qdisc的handle的y值必须是0,class的handle的y值必须是非0。通常"1:0"简写为"1:",也就是上面看到的写法。

default minor-id,未分类(不能和filter匹配)的流量(默认的)会被送到这个minor所指定的类(class id为major:minor-id),默认不指定就为0,即按物理链接的速率去发送。



tc class ... dev dev parent major:[minor] [ classid major:minor ] htb rate rate [ ceil rate ] burst bytes [ cburst bytes ] [ prio priority ]

 Class的参数:

parent major:minor,指定这个类的父节点,父节点可以是Qdisc,也可以是Class,如果是Qdisc,那么就不用指定minor,这个是必须的参数。

classid major:minor,classid作为class的标识,这个是可选的。如果这个class没有子节点,就可以不指定。major是父qdisc的handle。

prio 低优先级的class会优先匹配  

rate 这个class和其所有子类的速率

ceil 如果父类有空余带宽,最高可以分配给当前class的值,默认是和rate一样。

burst 允许以ceil的速率发送的字节数,应该至少和子类的burst最大值一样。  

cburst 允许以网口的最高速率发送的字节数,应该至少和子类的cburst最大值一样。功能类似tbf中的peakrate,当这个值限制很小时,可以避免突发的流量,以避免瞬间速率超过ceil。


quantum 每轮当前的class能发送的字节数,quantum = rate / r2q.  Quantum必须大于MTU(默认1500) 小于 60000。quantum只在class的流量超过了rate但是没超过ceil时使用。quantum越小,带宽共享的效果就越好。


r2q 用来计算quantum,r2q默认是10。Quantum设置的比MTU小会导致速率统计偏小,因为这种情况下速率计算的单位是Quantum,而不是真正发生的数据量。



例子:网络拓扑如下,有两个客户A和B,给B分配60kbps的带宽,给A分配40kbps的带宽,其中有30kbps分配给WWW,剩余的带宽分配给其他应用。下面的每一个节点都对应HTB中的一个class,当某个class没有用完分配的带宽,这些剩余的带宽可以分配给其他应用。

                        Main Link
                                | 100kbps
             --------------------------
              |  30kbps    |  10kbps   | 60kbps
       A/www         A/others       B

首先第一步先添加一个root的qdisc,为接口eth0指定HTB的qdisc,并用handle 1:来标识,default 12是指如果包没有匹配到接下来任何一个class,那么就放到默认的minor id为12的class中(classid 为 1:12)。

tc qdisc add dev eth0 root handle 1: htb default 12

接下来再为root的qdisc划分多个分类:

tc class add dev eth0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:10 htb rate 30kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:11 htb rate 10kbps ceil 100kbps
tc class add dev eth0 parent 1:1 classid 1:12 htb rate 60kbps ceil 100kbps

第一行创建了"root" class,父节点是"1:",root class下面的class之间是可以共享带宽的,直接把下面三个class挂载到"1:"也是可以的,但是它们之间就不会共享带宽了。

#不共享带宽

tc class add dev eth0 parent 1: classid 1:1 htb rate 30kbps ceil 100kbps
tc class add dev eth0 parent 1: classid 1:2 htb rate 10kbps ceil 100kbps
tc class add dev eth0 parent 1: classid 1:3 htb rate 60kbps ceil 100kbps

需要说明的是classid的作用域是在interface内的,即eth0或eth1都可以有同样的classid或handle id。

最后一步就是添加过滤规则,将特定的包放到指定的qdisc队列中,下面的flowid实际上就是classid。

tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4 match ip dport 80 0xffff flowid 1:10
tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip src 1.2.3.4 flowid 1:11


最后,可以给叶子节点的class指定qdisc,默认是pfifo,也可以用netem设置时延的丢包等。

tc qdisc add dev eth0 parent 1:10 handle 20: pfifo limit 5
tc qdisc add dev eth0 parent 1:11 handle 30: pfifo limit 5
tc qdisc add dev eth0 parent 1:12 handle 40: sfq perturb 10


使用tc命令时,最好是将这些命令都写入到bash文件中,例子如下:

#############################################################################
#!/bin/bash
set -v
# type your commands here


tc qdisc del dev eth0 root  --- deletes all tc configuration for eth0

# creates starting point for configuration on eth0 (and directs all unclasified trafic to class 5) optional
tc qdisc add dev eth0 root handle 2 htb default 5

# creates new class 8 which belongs to root 2
tc class add dev eth0 parent 2: classid 2:8 htb rate 135Kbit ceil 500Kbit prio 2

# attach the shaper itself to the class 8 if you will not use this fifo shaper will be used by default
tc qdisc add dev eth0 parent 2:8 sfq

# in the root place check if packet destination is 1.3 and then direct it to class 8
tc filter add dev eth0 parent 2: protocol  u32 match ip dst 192.168.1.3 classid 2:8
#############################################################################