Spring之优劣

背景

     作为InterONet的负责人, 在写Global平台的代码的时候, 有意无意间发现管理对象的生命周期是件很头大的问题, 虽然Java的GC机制, 在很大程度上避免了C++的管理对象的繁琐,但是, GC机制一旦在运行GC时,程序的“假死”现象也让人头疼。
     在InterONet迭代初期,所有的对象,都是靠new语句来进行的, 因此也具有强烈的耦合, 虽然“Program to Interface”这个法则一直深入我心, 不过在实例化对象时,难免用到具体类, 因此不能完全做到纯粹的“to Interface”。
      此时,GoF一书中所提及的Factory Pattern也许就是帮助来解决这个问题的一剂良药。此时,假设有一个框架能够帮助我(1)管理对象的生命周期(2)提供工厂模式 那也就再好不过了。
      所幸,Java的reflect特性正是可以用来做到上述的工作, 不过如果让我写InterONet之余, 再写一个这个框架, 岂不是有再造轮子之嫌, 俨然不符合作为互连网业内的“潜规则”。

IoC与DI

    IoC, 洋文全称为Inversion of Control,  我们常把其称为控制反转。 第一次接触到这个term是在耗子哥的Coolshell的这篇文章中,当时还觉得云里雾里, 不过时至今日, 也算是领会到耗子哥的良苦用心。
    为什么叫做控制反转呢, 俺就来解释一下: 所谓控制, 指的是你对于其他人的控制,譬如说你的代码里面new了一个别人写的类,那么你就在控制别人的对象。 所谓反转,指的是将这种控制交出去, 交给别人(第三方)来控制。 其实这里的思想我觉得跟三权分立有相似之处。 好吧,作为一个民工, 还是“莫谈国事”为好。
     看官肯定会想,如何交给第三方来做控制呢? 打个比方就特别好理解了, 两个企业, 其中A企业是你管的,B企业是别人管的。 现在A,B企业要合作, 那么B企业肯定要来人到你们企业喽, 那你就创建一个新的职位给B企业的员工,让他过来帮你干活, 这就是传统的new对象的模式。
这个员工是你创建的, 那么肯定你要负责他的衣食住行等等。 这是何等痛苦!!! 那如何减小这种痛苦呢? 那么,我找个中介公司来帮我管理吧, 让这个中介负责这个过来的员工的衣食住行以及工资等等。这不省事, 你过来只用干活, 干完就走。这样岂不是省事许多? IoC其实就是说的这个意思, 让一个第三方来帮你做管理, 反转了你的控制。
     其实, IoC就是这种思想, 好吧,各位看官看到这里, 是不是理解了IoC呢? 那么所谓DI又是什么概念?
     继续这个例子, 你需要B企业的人来帮你干活, 那么你怎么找到这个B企业的特殊的人呢?那么这就衍生出了Dependency Injection与Dependency Lookup, DI也就是说, 你在自己的公司门口写上“招聘B企业的哪个员工”, 中介自动把员工给你送过去, 而DL就是说, 你去中介公司去查花名册, 然后中介再把人给你送来。
      因此, DI与DL其实就是两种IoC的实现方式罢了。 因为DI更为方便, 因此, 大多时候, IoC也就约等于DI了。
      注:实现方式上面,洋文的维基百科跟中文的维基百科不太一样, 不过思想是类似的,洋文的写了
      这么多,不过, 我大体看了一眼, 其实思路差不多, 只是归类形式不同罢了, 关于实现方式不是本文和核心内容,就不再多说。

Spring IoC Container

    因为俺考虑到InterONet其实更多地在于业务逻辑, 而非性能, 因此InterONet也就用Java来作为主力语言。
    Java底下有相当多的IoC容器, HiveMind、PicoContainer、Spring Framework、Apache Excalibur、Seasar 和 DPML Metro 等。 其中除了Spring俺都没有见过。
Spring Framework是一个开源的JavaJava EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发布,也有.NET平台上的移植版本。该框架基于 Expert One-on-One Java EE Design and DevelopmentISBN 0-7645-4385-7)一书中的代码,最初由Rod Johnson和Juergen Hoeller等开发。Spring Framework提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。
    Spring的IoC Container作为整个SSH中中间层, 用来作解耦合是相当被业界推崇。 因此俺也就被其威名所吸引, 深入Spring, 了解其作用, 也为将来的工作后先预热一下。

优点

    关于优点, 俺就不再这里班门弄斧, 吹牛逼了。 直接搬运一下洋文的Wikipeida:
  • To decouple the execution of a task from implementation.
  • To focus a module on the task it is designed for.
  • To free modules from assumptions about how other systems do what they do and instead rely on contracts.
  • To prevent side effects when replacing a module.
     我就觉得第一条最重要,其他的几条感觉只要解藕了,都能推出来。

缺点

    作为一个深受马克思主义洗脑的爱国青年, 辩证主义深入我心。实际上, 主要是由于作为team leader, 必须做决策。囧。 那么废话少说了, 关于Spring有什么缺点呢?
  1. 难于调试。 毕竟依赖于别人的框架, 依赖于DI, 对于我new一个对象而言, 能追踪到对象的创建过程, 而较之于Spring而言, 这一部分是几乎无法追踪的。 因此调试上面,是肯定难于传统的方式。
  2. Spring学习曲线陡峭。对团队来说,是一次挑战。
  3. 框架重:有大约3000个类在其jar包内部,虽然其声称自己是轻量级。
  4. 需要详细的文档描述。

总结

   引用<Hamlet>一剧的经典名言: To Be or Not to Be, It is a question.

Exploit XJTU_WLAN(一)

背景介绍

     作为一名穷屌丝,用不起4G,只能靠蹭蹭学校的无线网。无奈,穷学校的无线帐号竟然只能提供给老师使用。着实让尔等屌丝伤透了心。

网页验证介绍

     OK,废话少说。渣校的XJTU_WLAN采用了网页验证方式,这个东西洋文叫做Captive Portal,首先连接进入未加密的XJTU_WLAN,接着通过DHCP客户端,请求分配IP地址,掩码,网关,DNS配置。关于这种Captive Portal不再做详细的说明,渣校的认证方式属于其中的Redirect by HTTP类型。

     这种认证方式巨大的劣势在于可以预先连接,并且获取到一个网络配置信息,这也就意味着,实际上我已经能够连入这个无线网络了。这无疑增加了我的手的机会。 再连入XJTU_WLAN,DHCP后,通过ipconfig命令,我发现我的网络配置信息如下。

IP:49.208.6.53/20
Gateway:49.208.0.1
DNS:202.117.0.20, 202.117.0.21

如何发现漏洞?

     各位看官看到如上的配置是否有有了一丝Hack的想法, 为何DNS跟本机不在一个网段,这里是否也就意味着本机可以利用DNS作为伪装与202.117.0.0/16的网内任意一台主机通信?

     笔者于是接下来就开始来验证这个答案。

$ nslookup www.baidu.com
Non-authoritative answer:
www.baidu.com    canonical name = www.a.shifen.com.
Name:    www.a.shifen.com
Address: 119.75.217.109
Name:    www.a.shifen.com
Address: 119.75.218.70

     看到如上的信息,立马就兴奋了起来。 DNS请求果真没有被拦截。好吧,DNS Tunnel肯定是毫无疑问可以去作了,利用iodine小程序即可搞定。 这个东西没有什么难度,我就不再说了。 只是因为笔者的VPS在国外,利用此种方式,实在是太慢。于是就放弃了这个想法。

     那我们继续考虑, 一般的防火墙还是没有GFVV这么这么牛逼了,不可能劫持DNS, 那么是否本机可以通过UDP53跟202.117.0.0/16任意一台机器通信?

     此处祭出神器netcat
@202.117.15.123/24 $ nc -u -l 53
@49.208.6.53      /20 $ nc -u 202.117.15.123 53

     不再贴图了,最终得到的答案是,可以进行收发包, 至此, 其实bypass XJTU_WLAN的工程已经完成了2/3。

如何绕过登录?

     随便找个udp tunnel的工具,进行一下端口转发一下,就可以了, 我用的是udptunnel(google code快关闭了,我已经将他迁移出去)。

server# ./udptunnel -s 202.117.15.123 53
client# ./udptunnel -c 127.0.0.1 3333 202.117.15.123 53 127.0.0.1 22
client# ssh -p 3333 user@127.0.0.1

     那对于小白而言,该如何操作呢?
     利用ssh不是可以打socks代理,win下利用proxifier软件,实现全局代理。linux下采用proxychains类似的工具可实现全局代理。
     本文不再详述ssh的socks代理的原理, SSH已经被用滥了,读者可自行搜索。

     在接下来的博文中,笔者会将分享如何利用虚拟网卡的方式来实现透明转发。
敬请期待!