2017年2月27日 星期一

废物利用老旧安卓平板流水账(三):android usb ethernet

这个平板已经作为网络服务器稳定工作了一段时间了,它已经成为我另一个计划的一部分,我还给它买了个usb有线网卡,这篇讲讲使用usb有线网卡时遇到的坑。

经验教训:不要买9700!

淘宝一搜usb有线网卡,按价格排序,你眼前会出现一大堆9700芯片的辣鸡货!这个自称10/100mbps的网卡其实搞的是假的100mbps!当它插在网络上时永远都会显示100mbps full,而实际效果只有10mbps half,并且与这个网卡连接的另一端也会显示连接速度为10 mbps half。我还一度认为这是驱动的bug,还天真的为了解决驱动的bug编译ko搞了内核hook,但是!完全!没有!用! 这个东西在windows下也是这个德行!9700这个芯片有很多名字,我知道的包括:SR9700QF9700RD9700,本质上都是同一个芯片,请注意不要跳坑。Dont buy any version of 9700 usb ethernet!!!!

命令行总结:

如果rom本身设置选项中包含有线局域网相关设置,那么很简单,完全用不上命令行。但是我这个rom不支持这个设置则需要在命令行中开启网络。
大多数情况下,只需要简单一行命令即可完成设置:netcfg eth0 up dhcp
但是假如你想要手工分配ip等信息,可以使用以下命令:

netcfg eth0 up
ifconfig eth0 192.168.0.123 netmask 255.255.255.0
route add default dev eth0
route add default gw 192.168.0.1 dev eth0
setprop net.eth0.dns1 8.8.8.8
setprop net.eth0.dns2 8.8.4.4

其中route add default gw是添加默认网关的命令,其他命令想必已经很明白了,就不一一解释了。
如果需要强制指定网卡工作模式则需要交叉编译ethtoolethtool的示例如下:

ethtool -s eth0 speed 10 duplex half autoneg off

如果还有不明白的地方可以参考:HowTo : Change Speed and Duplex of Ethernet card in Linux
在此基础上,如果还需要指定系统代理,可以参考Andrord Networking这个wiki,不过这个设置代理的方式我并没有尝试,不确定到底能否使用。
如果设备过一段时间就连不上了,同时设备自身却运行正常,可以尝试写一个脚本每隔一段时间执行一次netcfg eth0 dhcp

解决锁屏断电问题:

我用的这个rom在屏幕锁屏时usb otg就不再工作了,这一点对于网络服务器来讲是致命的。所以需要解决两个问题,1.系统不要进入休眠、2.屏幕应该正常关闭(省电)。
首先,想要屏幕不休眠有两种办法,第一种是在Developer options中选上Stay awake,这样系统就不会进入休眠了。
第二种是使用以下命令:

echo on>/sys/power/state
echo my_lock>/sys/power/wake_lock

这时屏幕将会常亮usb otg将会持续工作,但是平板作为服务器如果屏幕常亮那耗能太多了,虽然手工按一次esc键可以让平板关掉屏幕,但谁能接受自己的网络服务器每次reboot都需要手工物理接触一次才能不费电?
为了解决这个问题,可以使用以下命令模拟一次esc按键,来关闭屏幕:

input keyevent 26

在不同的rom版本26可能是不同的值,可能是27或者别的什么,可以自行尝试。

网络参数优化:

网络参数优化的文章很多,这里不打算对参数进行详述。这里要提醒的是修改net.ipv4.tcp_rmem等参数时,不要尝试修改build.prop了,没用的。用sysctl:

sysctl -p your_config_file

最后:

如果把安卓设备作为网络服务器来使用的话,给设备配上一个usb有线网卡还是值得的,内网延迟基本没有了,同时请一定要注意不要购买9700系列芯片的产品。下一篇讲移植ssh到安卓并干掉dalvik虚拟机,让平板更加符合网络服务器的定位。

2016年12月14日 星期三

备忘:Blogger Simple模板缩短订阅按钮用到的css

.subscribe-dropdown-arrow {
    display: none !important;
}
.subscribe {
    width:97px !important;
}
.subscribe .top{
    width:97px !important;
    background:none !important;
}
.subscribe .bottom{
    width:97px !important;
    background:none !important;
}

2016年12月9日 星期五

废物利用老旧安卓平板流水账(二):交叉编译shadowsocks


在上一篇流水账中我已经有了个能用的ROM,然而这个android系统还是太老了,在这个系统上并不能支持最新版的shadowsocks安卓app,而旧版本的shadowsocks没有自带kcptun,不知道为什么也没法通过我手工启动的kcptun连上服务器。所以只好放弃使用app,手工编译一个ARM指令集的native shadowsocks客户端程序。

这篇包含两部分,前一部分是使用NDK交叉编译shadowsocks-libev,后一部分是使用go交叉编译shadowsocks-go

使用NDK交叉编译shadowsocks-libev:

由于这是一次失败的尝试,同时我在写这篇文章的时候也是在回忆了,所以这部分重心放在记述如何使用NDK交叉编译可以运行在androidnative程序而不是ss,有些细节可能略过了。
首先需要去这里下载一份NDK。由于我只是需要交叉编译个native程序而已,并不是要搞app开发,所以只要使用standalone toolchain就好。
按照这里的步骤NDK创建出适用于自己的android平台的standalone toolchain。如果直接使用ndk目录内的toolchain你可能会遇到像这里或者这里还有这里遇到的诸如“fatal error: string: No such file or directory”或者“undefined reference to `std::basic_string”之类的编译错误,由于我们不是android工程没有使用ndk-build所以创建Application.mk文件的办法并不管用。
之后编译opensslpcrelib库,在执行configure之前先设置环境变量让make的时候使用我们的toolchain(将'/my-android-toolchain-path替换为你的toolchain目录):

export ANDROID_TOOLCHAIN='/my-android-toolchain-path/'
export CC=${ANDROID_TOOLCHAIN}/bin/'arm-linux-androideabi-gcc --sysroot='${ANDROID_TOOLCHAIN}/sysroot
export CXX=${ANDROID_TOOLCHAIN}/bin/'arm-linux-androideabi-g++ --sysroot='${ANDROID_TOOLCHAIN}/sysroot
export CCLD=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-ld
export AR=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-ar
export AS=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-as
export RANLIB=${ANDROID_TOOLCHAIN}/bin/arm-linux-androideabi-ranlib

configure的时候记得添加这几项:
--host=arm-linux 指定编译目标系统环境
--with-sysroot=/my-android-toolchain-path/sysroot 指定sysroottoolchain
--prefix=/my-android-toolchain/sysroot/usr 指定安装目录到toolchain

之后编译shadowsocks-libev仍然并不顺利,因为这个工程并没有做好在NDK编译的工作,指定-DANDROID,手工添加编译ancillary和添加-llog引用等一系列工作完成后编译出来的程序并不能正常工作,于是我把视野转向了shadowsocks-go

交叉编译shadowsocks-go:

其实如果COW或者MEOW这种自动化的工具更合你的口味的话,你完全不需要自己去编译shadowsocks-go,因为他们都提供了ARM版本的bin。而对于我来说,他们都不是我的菜。
由于我完全没有go编程经验,所以我这里的一些对go的理解很可能是错误的,请自行思考并有选择的接受我的看法。
Go的交叉编译很简单,按照下面的顺序执行即可:
yum install -y golang
安装go

export GOARCH=arm
指定go编译的指令集

https_server=127.0.0.1:1234 go get github.com/shadowsocks/shadowsocks-go/cmd/shadowsocks-local
因为golang.org被墙了,所以这里指定了https代理服务器127.0.0.1:1234

之后就可以在/lib/golang/bin/linux_arm路径下找到arm版的shadowsocks-go了。

接下来我做了什么?在平版上安装了ssh服务,然后结合kcptun + shadowsocks-go + privoxy搞了个内网公用服务器。这三个组合起来在安卓上搞内网服务并没有啥难度,我不确定会不会单开一篇详述。另外最近才发现privoxy真的很强大呢,完全超越了PAC的灵活性(见这里这里