首先我面壁,我是码农!
我公司有一套自己写的log组件,这个组件最大的神奇之处就在于跨进程的log。这个是我第一次见,之前写的程序也没有这方面需求,只是自己log写文件就ok了。
但是我有个想法,这跨进程挺好的,可是万一我想跨机器log了,这不就嗝屁了吗?
不行!
于是自己折腾了一个log。当然是通过tcp了,这样有网络就行了。整个log只用了一个锁,跨进程间是不会互相影响的。即便这个锁,也是加在一个循环队列的buffer上的。以后完全有可能使用无锁的方式优化掉,这就相当于这个log组件完全无锁。唯一的缺点就是需要跑一个logserver来接收程序的log,当然你也是连在这个server上看log的。同时正在做一个web的前台,用户可以再前台设置log级别,查看log。最后,亲,跨平台的哦,支持windows/linux , c、c++、java哦,欢迎购买,包邮哦!
目前粗则了下性能,本机能够达到每秒5w+,log一个不丢。比较了下,功能没有log4cxx强大,但速度比log4系列的有优势。而且可以动态调整log级别。另外,在log极多的情况下,查看log的用户数越多,性能会下降。
然后,我深知诸多大神鄙视这种造轮子的行为,可TMD的真的没找到能跨机器log的东西啊啊啊啊啊。。。。。
log4CXX到是有socket的appender,可那个东西的效率实在不能接受的。
下面主要说具体的做法:
其实这玩意说白了就两件事:
1、从tcp接收纯文本。
2、把文本从tcp发出去。
但搞对了就不那么容易了,搞好了,就更难了。
如果你尝试写一个,你会发现以下的问题
1、tcp粘包的,拆包的问题。既如何区分出一条完整的log,这个不难。
2、网络异步的发送和接收。当然不能用同步的,那会导致导致恩你自己想。。。
3、log的格式自定义,这个有点难度。
4、动态log级别调整,这个也有难度。
5、网络异常后自动恢复。这个不难。
搞好了,就涉及到以下问题。
1、尽一切可能减少copy。这个用了shareptr来解决。
2、尽可能减少malloc。这个找了一个mempool来解决。(效果不明显)
3、在lan上是没有问题,在wan上就需要考虑数据的压缩。log都是纯文本,压缩来减少数据传送。当然,配套的读log的东西也是要自己写的。
4、多线程的问题,每连接一个线程的模型是不能接受的。事实上,数据接收和处理各有一个线程,两个线程而已(当然线程数目是可以配置的)。数据接收和发送各有一个thread pool。
5、界面。这个仁者见仁了,可能大部分人认为log还有个界面,不能理解。事实上,这玩意很有用,真的!
插播新闻:c++0x上个星期投票通过了!!!
boost是个好东西,居家旅行,杀人放火必备良器。boost:: shared_ptr boost::function boost:: bind boost::asio这些东西都太犀利了。 当然学习成本是有点高,而且这玩意难调得一腿啊,当时少写了个括号,报了几十个错误,还没一个错误正确指出错误的地方,shit!不过用熟悉了,也就知道怎么回事了,运行时错误,跟到boost代码里面,大部分也都豁然开朗了。现在公司里面就用stl,我经常想,要是这玩意用boost,至于写那么多线程,那么多锁吗。。。。还有就是那个ptlib,也不是说它不好,可是这玩意太小众了,还有一堆莫名其妙的地方。资料也木有,只能看源码,不过我也不想看,有时间看他的,还不如看看boost的。
看源码的话,现在小有点经验了,体验也多了,记得以前最怕看别人写的东西。在调程序的时候,看到boost的源码,当时就想说tnnd,竟然可以这样写。。。
今天就废话这么多,看哈利波特去了。
今天终于搞通了android to any voice。
其实android到gtalk,到msn,这些都不是问题,到qq这个不要想了,sigh!
主要是找到一家可靠的sip服务商,资费足够便宜,通话清晰。我用的LocalPhone,他到china的费率是0.12rmb,比市话便宜。在android上用fring做为sip的接入端。fring也支持msn,gtalk等。你要是在用个google voice就更好了。
顺便推荐一个美剧真爱如血,比较赞,(HBO出品,口味比较重)
情况是这样的,使用helix做rtp relay服务器,后来发现在server2003下helix工作ok,在linux下,无法工作。
我抓狂啊!
好吧!我来查,会不会是操作系统的问题?ok,我装了rad hat 4,我装了centos,还是依旧。好吧,会不会是虚拟机的问题?我上服务器上测。still,我想跳楼了。。。。。
然后我怀疑sdp的问题,我直接把server2003下可以正常工作的文件拷过了,还是不行。。。
然后折腾了两天,终于发现vlc生成的sdp中,源使用windows机器名,放linux当然跑不起来。。。。。。
疯了。。。。。。。。。。。。
This document illustrates that the order in which transactions are processed using Network Address Translation (NAT) is based on whether a packet is going from the inside network to the outside network, or from the outside network to the inside network.
Readers of this document should have knowledge of the following topic:
This document is not restricted to specific software and hardware versions.
Note: The information in this document is based on the Software Version, Cisco IOS® Software Release 12.2(27)
For more information on document conventions, refer to the Cisco Technical Tips Conventions.
(全文…)
http://www.rfc-editor.org/rfc/rfc3330.txt
Address Block Present Use Reference
---------------------------------------------------------------------
0.0.0.0/8 "This" Network [RFC1700, page 4]
10.0.0.0/8 Private-Use Networks [RFC1918]
14.0.0.0/8 Public-Data Networks [RFC1700, page 181]
24.0.0.0/8 Cable Television Networks --
39.0.0.0/8 Reserved but subject
to allocation [RFC1797]
127.0.0.0/8 Loopback [RFC1700, page 5]
128.0.0.0/16 Reserved but subject
to allocation --
169.254.0.0/16 Link Local --
172.16.0.0/12 Private-Use Networks [RFC1918]
191.255.0.0/16 Reserved but subject
to allocation --
192.0.0.0/24 Reserved but subject
to allocation --
192.0.2.0/24 Test-Net
192.88.99.0/24 6to4 Relay Anycast [RFC3068]
192.168.0.0/16 Private-Use Networks [RFC1918]
198.18.0.0/15 Network Interconnect
Device Benchmark Testing [RFC2544]
223.255.255.0/24 Reserved but subject
to allocation --
224.0.0.0/4 Multicast [RFC3171]
240.0.0.0/4 Reserved for Future Use [RFC1700, page 4]
To be “up/up,” a router VLAN interface must fulfill the following general conditions:
•
The VLAN exists and is “active” on the VLAN database of the switch.
•
The VLAN interface exists on the router and is not administratively down.
•
At least one Layer 2 (access port or trunk) port exists, has a link “up” on this VLAN and is in spanning-tree forwarding state on the VLAN.
昨天Mantasano上的一篇文章描述了Dan Kaminsky的DNS域名服务器攻击的细节。该文章发表了几分钟之后即被删掉了。
虽然Dan Kaminsky已经联合厂商发布了补丁,但是仍处于补丁推送阶段,目前仍有相当一部分域名服务器还没有打补丁。如果被恶意利用的话,对整个互联网还是很有威胁的。这也是为什么Dan 希望 “not speculate publicly”。
大概看了一下那篇hypothesis,基本上还是利用了”Cache 投毒”(cache poisoning)的方法,不过使用了一些新的技巧。
DNS查询是如何进行的?对于绝大多数桌面系统来说,DNS的查询并不是由自己的机器完成的,DNS查询会提交给另一台DNS服务器(这台服务器通常是由 ISP或者公司提供),然后这台服务器再去进行真正的查询操作。这样做的好处是DNS的查询结果可以由这台机器给缓存下来,从而提高查询效率并降低由 DNS带来的流量开销。
一台缓存DNS服务器(与权威DNS相对,这类系统提供的)下面的桌面系统可能有几百、几千、几万甚至几十万台桌面系统。
DNS缓存中毒攻击指的是更改了DNS服务器的DNS缓存中某项,这样缓存中与主机名相关的IP地址就不再指向正确的位置。例如,如果 www.example.com映射到IP地址192.168.0.1且DNS服务器的缓存中存在这个映射,则成功向这个服务器的DNS缓存投毒的攻击者就可以将www.example.com映射到10.0.0.1。在这种情况下,试图访问www.example.com的用户就可能与错误的Web服务器联络。
当攻击者试图请求查询某站点的域名时,DNS服务器首先会检查自己的DNS缓存中是否存在该域名,如果存在则将该域名所对应的IP地址返回给请求者,如果不存在则向上一级DNS或者权威DNS查询。这就会给攻击者带来一定的困难,如果是大一点的站点的话,攻击者发起DNS查询时,DNS服务器直接从缓存应答了,根本不会去请求权威域名服务器。怎么才能解决这个问题呢?云舒在他的DNS缓存中毒漏洞的一点推测中也提到过。
比如我们要攻击www.google.com.首先向目的DNS服务器查询根本不存在的二级域名,比如:aaa.google.com. DNS服务器在缓存中查找aaa.google.com,没有找到,则会向上级DNS或者权威DNS查询 。这时我们可以生成伪造的DNS Response数据包并发送这些的伪造DNS Response数据包给目的服务器。让目的DNS在上级DNS或者权威DNS服务器响应到达之前,接受到恶意的应答。
从表面上看这样只是截持了一个不存在的二级域名,只能用来钓钓鱼罢了。
其实DNS Response数据包可以不仅仅包含aaa.google.com的IP地址,还可以在DNS 数据包的Additional resource record中包含www.google.com的IP地址(当然该IP地址可以是伪造的)。当目的DNS收到该数据报时会将伪造的IP地址与 www.google.com关联起来并刷新到缓存上。这样就完成了主域名的截持。
by 云舒
今天抽空看了下emule协议几个可能会出问题的地方,初步感觉是可能真的有问题。下了代码回来看了,不过代码太大,目前还没找到地方,没法对想法进行印证。我简单的说下,看哪位代码牛人能够在项目中找到对应的代码。
首先是在客户端连接到服务器之后,搜索文件时,服务器返回结果的报文。报文中返回的结果是一个集合,每个集合表示一条记录。但是每条记录中,并不包含拥有该文件的客户端的IP地址,而是返回的拥有该文件的客户端的ClientID和端口。这里我猜测ClientID的计算是可逆的,搜索发起者可以根据这个 ClientID计算出IP地址,然后连接,请求下载文件。具体报文结构如下:
| 名称 |
大小(字节) |
默认值 |
注释 |
| 协议类型 |
1 |
0xE3 |
|
| 大小 |
4 |
|
不包含报文和大小域的报文大小 |
| 类型 |
1 |
0×16 |
操作码 OP SEARCHRESULT 的值 |
| 结果数 |
4 |
N/A |
此报文中包含的结果数目 |
| 结果列表 |
可变 |
N/A |
一个结果的列表 |
搜索结果列表项格式:
| 名称 |
大小(字节) |
默认值 |
注释 |
| 文件HASH |
16 |
N/A |
用于识别文件的 Hash 值 |
| 客户端 ID |
4 |
N/A |
eMule服务器分配给客户端的ID |
| 客户端端口 |
2 |
N/A |
客户端的监听的TCP端口 |
| 标志数 |
4 |
N/A |
其后的属性标志个数 |
| 标志列表 |
可变 |
N/A |
标志列表 |
其次的第二个地方是下载文件的地方,客户端要求下载一个文件时,服务器会返回一个源查找结果报文。该报文也是只包含源的ClientID和端口,客户端应该是按照ClientID计算出IP地址,再去连接下载文件的。具体报文如下:
| 名称 |
大小(字节) |
默认值 |
注释 |
| 协议类型 |
1 |
0xE3 |
|
| 大小 |
4 |
N/A |
不包含报文头和大小域的报文大小 |
| 类型 |
1 |
0×42 |
操作码 OP FOUNDSOURCES 的值 |
| 文件HASH |
16 |
N/A |
相关文件的 Hash 值 |
| 源数量 |
1 |
N/A |
拥有该文件的机器的数量 |
| 源列表 |
可变 |
N/A |
源列表内容,每一条是一个可用源 |
每一条源的报文格式如下:
| 名称 |
大小(字节) |
默认值 |
注释 |
| 客户端 ID |
4 |
N/A |
共享该文件的客户端的 ID |
| 客户端端口 |
2 |
N/A |
共享该文件的客户端端口 |
可以看到,搜索某个文件时,服务器返回的搜索列表中按照ClientID来区分不同的其它客户端。在开始下载一个文件时,服务器返回的可用源列表中,每个源也是以一个ClientID来表示的。也就是说,没一个ClientID就可以确定一个源,区分开彼此。而emule可以根据这个ClientID找到对应的客户端,去连接指定端口,请求文件。那么,现在的问题是这个ClientID是哪里来的?
原来这个ClientID在正常情况下,是我们连接到emule服务器时,服务器分配给我们的。但是注意到,在连接之后,我们可以像服务器提供我们所拥有的文件列表,报文格式如下:
| 名称 |
大小(字节) |
默认值 |
注释 |
| 协议类型 |
1 |
0xE3 |
|
| 大小 |
4 |
|
不包含报文和大小域的报文大小 |
| 类型 |
1 |
0×15 |
操作码 OP SEARCHRESULT 的值 |
| 文件数 |
4 |
N/A |
共享列表中的文件数,这个数不超过 200 |
| 文件列表 |
可变 |
N/A |
可选的文件列表,单个项的描述见下 |
单个文件条目描述我就不细写了,比较有用的字段是文件Hash码,ClientID,以及端口。这样看来,我们在连接到服务器之后,告诉它baidu的IP地址,TCP80端口,有赤壁下载,或者有XXX片下载,别人下载的时候,emule客户端会不会从服务器返回的可用源列表中,找到这条记录,并且去连接?
关键问题到了ClientID的计算,协议中这样描述的:假设 IP 地址为 X.Y.Z.W,则客户端 ID 按公式 X+28*Y+216*Z+24*W (Big Endian[6])计算。如果想法是正确的,那么我们可以先计算出百度的IP地址的ClientID,端口设置为80,然后通知服务器,这个 ClientID有高树的片子可以看……
Recent Comments
@又秀逗了
@Waiting U Here
@贴一个自己用的log4j配置的模板
@评论开启
@今天过生日