双层SSH隧道研究

学校的内网无法直接出校, 需拨某VPN才能访问外网, 对外统一为一个ip. 然而最近由于那啥升级导致学校的国际出口及其不稳, 无法通过此VPN挂SSH proxy. 手头有一系服务器(Server A)对外有独立ip, 然而没有root权限, 基本上只能ls/cp/mv/rm/scp. 突然想到既然可以ssh上此服务器当然可以当成proxy出校, 而且由于独立ip基本没有对外访问的请求应该不至于触发某计数器, 于是尝试在此ssh tunnel中再与vps(Server B)构造一层tunnel.

由于没有root权限也改不了iptables, Server A自然只能当成ssh proxy出校用了, 在本地8000端口监听:

ssh -qTfnN -D 8000 user@server-a.com

尝试让本地的ssh请求走8000端口的proxy, 然而全局代理无效, 只能另想办法.

Google了一圈发现proxychains, 支持HTTP/SOCKS4/SOCKS5, 支持ssh/telnet/wget/ftp/apt/vnc/nmap等命令的转发, 再合适不过了.

直接apt-get装完, 编辑/etc/proxychains.conf如下, 具体可参照该文件内的注释:

dynamic_chain
chain_len=1
proxy_dns 
tcp_read_time_out 15000
tcp_connect_time_out 10000

[ProxyList]
socks5 	127.0.0.1 8000
socks4  127.0.0.1 8000

配置完后就可以在通过代理使用ssh了:

sudo proxychains ssh -qTfnN -D 7070 user@server-b.com

此后配置浏览器通过7070端口使用代理, 即可正常访问.

Advertisements

C++判断输入结束的讨论

先看2段代码:

[cpp title=”Method 1″]

int a;
while(cin>>a)
{
cout<<a<<endl;
}

[/cpp]

[cpp title=”Method 2″]

int a;
while(cin.good())
{
cin>>a;
cout<<a<<endl;
}

[/cpp]

乍一看, 两者似乎都能判断出输入结束, 然而, 当输入出现错误时, 看下列例子:

input:
1 2 a
output 1:
1
2
output 2:
1
2
2

第二种方法却多了一个输出. 仔细观察, 发现两者从输入流读取和判断结束的顺序存在不同:

Method 1:
从输入流读取->判断流的状态->输出->…
Method 2:
判断流的状态->从输入流读取->输出->…

当循环进行到第三次时, Method 1先进行读取, 发现’a’不满足int, 于是返回0, 跳出循环, 故有2次输出. 而Method 2 先进行判断, 由于此时刚刚成功读完第二个数据, 第三个还未读, 流的状态cin.good()为true, 故进入第三个循环, 尝试读入一个数, 发现’a’不满足int, 于是a的值不会被覆盖, a的值仍为2, 故又输出一个2. 之后由于刚才读取失败置cin.good()为false, 跳出循环.
可见, 用cin.good()判断输入结束是可能存在问题的, 需作如下修改:

[cpp title=”Method 3″]
int a;
cin>>a;
while(cin.good())
{
cout<<a<<endl;
}

[/cpp]

此时先进行读取再判断流的状态, 可以正常判断输入结束.

另外, 参考http://www.cplusplus.com的解释, 如下情况时cin.good()会被置false:

“The function returns true if none of the stream’s error flags (eofbit, failbit and badbit) are set.”

即eofbit, failbit, badbit中任何一个被触发即置cin.good()为false.
注意到cin.bad()并不是cin.good()的反面, 它只对应badbit.
关于这三个标志何时被触发有下表:

flag error
eofbit The end of the source of characters is reached during its operations.
failbit The input obtained could not be interpreted as an element of the appropriate type.

Notice that some eofbit cases will also set failbit.

badbit An error other than the above happened.

输入结束将导致eofbit和failbit, 输入类型不符将导致failbit, 其它将导致badbit.

吐槽: 这货害我在ZOJ上浪费了不下30次submit…

IIS上WordPress的固定链接问题

IIS上WordPress的固定链接不能做成这样的形式:

IIS上WordPress的固定链接问题


上面的链接默认会404, 只能弄成如下形式:
http://archangelsdy.com/index.php/2010-12/iis-wp-static-link/
这样未免不太完美, 不过既然会404, 就可以在404页面上动点手脚, 一下是网上流传较广的404重定向修改页:


<?php
header("HTTP/1.1 200 OK");
$ori_qs = $_SERVER['QUERY_STRING'];
$pattern = '/[^;]+;[^:]+://[^/]+(/[^?]*)(?:?(.*))?/i';

preg_match($pattern, $ori_qs, $matches);
$_SERVER['PATH_INFO'] = $matches[1] . '?' . $matches[2];
$_SERVER['REQUEST_URI'] = $_SERVER['PATH_INFO'];
$query_args = explode('&', $matches[2]);
unset($_GET);
foreach ($query_args as $arg)
{
$the_arg = explode('=', $arg);
$_GET[$the_arg[0]] = $the_arg[1];
}

include('index.php');
?>

这个404.php挂了上去后, 链接是重定向正常了, 不过顶上华丽地顶着3个”offset error”, 貌似是数组越界, 看了下代码(其实完全不懂php…), 用到了$matches[]这个数组, 第一反应是添行if(count($matches)>=3)上去, 没想到真的成功了! 不知道有没有什么后遗症捏…

附改过的404.php, 有的主机可能要另外设一下404页面的位置.


<?php
header("HTTP/1.1 200 OK");
$ori_qs = $_SERVER['QUERY_STRING'];
$pattern = '/[^;]+;[^:]+://[^/]+(/[^?]*)(?:?(.*))?/i';

preg_match($pattern, $ori_qs, $matches);
if(count($matches)>=3)
{

$_SERVER['PATH_INFO'] = $matches[1] . '?' . $matches[2];
$_SERVER['REQUEST_URI'] = $_SERVER['PATH_INFO'];
$query_args = explode('&', $matches[2]);
unset($_GET);
foreach ($query_args as $arg)
{
$the_arg = explode('=', $arg);
$_GET[$the_arg[0]] = $the_arg[1];
}

}
include('index.php');
?>