今天更新系统的时候发现升级了一个libnghttp2库文件,好奇查看了一下:

pacman -Qi libnghttp2
名字           : libnghttp2
版本           : 1.29.0-1
描述           : Framing layer of HTTP/2 is implemented as a reusable C library
架构           : x86_64
URL            : https://nghttp2.org/
软件许可       : MIT
组             : 无
提供           : 无
依赖于         : glibc
可选依赖       : 无
要求被         : curl
被可选依赖     : 无
冲突与         : nghttp2<1.20.0-2
取代           : 无
安装后大小     : 337.00 KiB
打包者         : Jan de Groot <jgc@archlinux.org>
编译日期       : 2017年12月26日 星期二 06时39分21秒
安装日期       : 2018年01月05日 星期五 21时23分48秒
安装原因       : 作为其他软件包的依赖关系安装
安装脚本       : 否
验证者         : 数字签名

原来是被curl依赖的, 我意识到curl已经支持http2了,测试一下,果然:

curl -v --http2 https://kexiao8.com/
...
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x562250ec3160)
> GET / HTTP/2
> Host: kexiao8.com
> User-Agent: curl/7.57.0
> Accept: */*

看一下官方文档:Starting in 7.43.0, libcurl fully supports HTTP/2 multiplexing, which is the term for doing multiple independent transfers over the same physical TCP connection.
`curl offers the --http2 command line option to enable use of HTTP/2.
Since 7.47.0, the curl tool enables HTTP/2 by default for HTTPS connections.`

以前我的线上某一台服务器有eth0eth1两个网卡,分别对应内外网不同网络。但是有一次用命令dstat -N eth0,eth1tcpdump监测网络的时候发现,发往eth0的IP的流量居然会从eth1网卡流入流出, 这两个ip的网段和路由没有任何联系。 当时震惊了一下,分析原因,因为当初为了节约交换机,这两个网卡插在相同的一台交换机上,而且没有VLAN。由于网络ip层不应该有问题, 所以应该是链路层造成的结果,可能是ARPMac寻址的结果,后来没有深究。
很久以后,出现了一个新的问题:配置iptables的时候,规则DROP无效,于是又找回这里。iptables精简配置如下:

# Generated by iptables-save v1.4.14 on Wed Sep 13 18:05:35 2017
*raw
:PREROUTING ACCEPT [69675:4914196]
:OUTPUT ACCEPT [54936:3566904]
-A PREROUTING -p tcp -m tcp --dport 13306 -j TRACE
COMMIT
# Completed on Wed Sep 13 18:05:35 2017
# Generated by iptables-save v1.4.14 on Wed Sep 13 18:05:35 2017
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [93762:6266296]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth1 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 13306 -j DROP
-A INPUT -p icmp -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
COMMIT

从上可知, 默认允许lo和eth1内网所有流量, 拒绝了外网eth0的6379, 但是事实上可以从外网从容访问13306端口。

打开iptables的调试:

sudo modprobe ipt_LOG
iptables  -t raw -A PREROUTING  -p tcp --dport 13306 -j TRACE
sudo tail /var/log/kern.log

得到访问日志:

Sep 13 17:49:21 host239 kernel: [141463786.397726] TRACE: raw:PREROUTING:policy:2 IN=eth1 OUT= MAC=90:b1:1c:36:34:2c:70:54:f5:9d:bc:7b:08:00 SRC=59.151.**.** DST=113.31.*.* LEN=52 TOS=0x00 PREC=0x00 TTL=48 ID=45702 DF PROTO=TCP SPT=49983 DPT=13306 SEQ=296903697 ACK=934588750 WINDOW=115 RES=0x00 ACK FIN URGP=0 OPT (0101080A4BD6D6963FB18493) 
Sep 13 17:49:21 host239 kernel: [141463786.397760] TRACE: filter:INPUT:rule:1 IN=eth1 OUT= MAC=90:b1:1c:36:34:2c:70:54:f5:9d:bc:7b:08:00 SRC=59.151.*.* DST=113.31.*.* LEN=52 TOS=0x00 PREC=0x00 TTL=48 ID=45702 DF PROTO=TCP SPT=49983 DPT=13306 SEQ=296903697 ACK=934588750 WINDOW=115 RES=0x00 ACK FIN URGP=0 OPT (0101080A4BD6D6963FB18493)

上面有神奇的是,日志中外部访问13306端口的流量指向的外网ip(属于eth0), 但是日志记录的是IN=eth1, 且mac address 90:b1:1c:36:34:2c 属于eth1。这简直是以前内外网混流量问题的翻版。研究了一下,虽然关键词贫乏google很久没有有效信息, 想起以前用vpn的时候arp_proxy相关配置似乎有些关联性, 用arp继续google,发现关键词arp_announce

arp_announce - INTEGER
    Define different restriction levels for announcing the local
    source IP address from IP packets in ARP requests sent on
    interface:
    0 - (default) Use any local address, configured on any interface
    1 - Try to avoid local addresses that are not in the target's
    subnet for this interface. This mode is useful when target
    hosts reachable via this interface require the source IP
    address in ARP requests to be part of their logical network
    configured on the receiving interface. When we generate the
    request we will check all our subnets that include the
    target IP and will preserve the source address if it is from
    such subnet. If there is no such subnet we select source
    address according to the rules for level 2.
    2 - Always use the best local address for this target.
    In this mode we ignore the source address in the IP packet
    and try to select local address that we prefer for talks with
    the target host. Such local address is selected by looking
    for primary IP addresses on all our subnets on the outgoing
    interface that include the target IP address. If no suitable
    local address is found we select the first local address
    we have on the outgoing interface or on all other interfaces,
    with the hope we will receive reply for our request and
    even sometimes no matter the source IP address we announce.

于是解决方法是:

echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

或者把iptables的-A INPUT -i eth1 -j ACCEPT换成-A INPUT -s 192.168.0.0/16 -j ACCEPT

回顾一下,这个"bug"其实很隐蔽, 因为iptables的配置看起来完美无缺, 但是, 但是, 谁知道问题出现在链路层。

现在compton已经在debian/ubuntu的默认apt库里面了。
速度上来说也比以前流畅不少,但是因为linux下的所有显卡的驱动和性能都是一如既往的差劲,所以为了让阴影效果和UI响应更流畅些,需要把compton的引擎改为glx来获得更好的体验。
另外一点是,开启compton的情况下,firefox的滚屏速度和flash的CPU都会有影响, 这一点上可以通过XLIB_SKIP_ARGB_VISUALS=1来提高,而这一个配置最好不要设置为全局的,因为它会让浮动窗口比如:fcitx和Docky等等的背景出现黑色的方框, 所以直接在/usr/bin/firefox中插入一行export就好了。

具体的.compton.conf如下:

#################################
#
# Backend
#
#################################

# Backend to use: "xrender" or "glx".
# GLX backend is typically much faster but depends on a sane driver.
backend = "glx";

#################################
#
# GLX backend
#
#################################

glx-no-stencil = true;

# GLX backend: Copy unmodified regions from front buffer instead of redrawing them all.
# My tests with nvidia-drivers show a 10% decrease in performance when the whole screen is modified,
# but a 20% increase when only 1/4 is.
# My tests on nouveau show terrible slowdown.
# Useful with --glx-swap-method, as well.
glx-copy-from-front = false;

# GLX backend: Use MESA_copy_sub_buffer to do partial screen update.
# My tests on nouveau shows a 200% performance boost when only 1/4 of the screen is updated.
# May break VSync and is not available on some drivers.
# Overrides --glx-copy-from-front.
# glx-use-copysubbuffermesa = true;

# GLX backend: Avoid rebinding pixmap on window damage.
# Probably could improve performance on rapid window content changes, but is known to break things on some drivers (LLVMpipe).
# Recommended if it works.
# glx-no-rebind-pixmap = true;


# GLX backend: GLX buffer swap method we assume.
# Could be undefined (0), copy (1), exchange (2), 3-6, or buffer-age (-1).
# undefined is the slowest and the safest, and the default value.
# copy is fastest, but may fail on some drivers,
# 2-6 are gradually slower but safer (6 is still faster than 0).
# Usually, double buffer means 2, triple buffer means 3.
# buffer-age means auto-detect using GLX_EXT_buffer_age, supported by some drivers.
# Useless with --glx-use-copysubbuffermesa.
# Partially breaks --resize-damage.
# Defaults to undefined.
glx-swap-method = "undefined";

#################################
#
# Shadows
#
#################################

# Enabled client-side shadows on windows.
shadow = true;
# Don't draw shadows on DND windows.
no-dnd-shadow = true;
# Avoid drawing shadows on dock/panel windows.
no-dock-shadow = false;
# Zero the part of the shadow's mask behind the window. Fix some weirdness with ARGB windows.
clear-shadow = true;
# The blur radius for shadows. (default 12)
shadow-radius = 3;
# The left offset for shadows. (default -15)
shadow-offset-x = -5;
# The top offset for shadows. (default -15)
shadow-offset-y = -5;
# The translucency for shadows. (default .75)
shadow-opacity = 0.85;

# Set if you want different colour shadows
shadow-red = 0.03;
shadow-green = 0.03;
shadow-blue = 0.04;

# The shadow exclude options are helpful if you have shadows enabled. Due to the way compton draws its shadows, certain applications will have visual glitches
# (most applications are fine, only apps that do weird things with xshapes or argb are affected).
# This list includes all the affected apps I found in my testing. The "! name~=''" part excludes shadows on any "Unknown" windows, this prevents a visual glitch with the XFWM alt tab switcher.
shadow-exclude = [
#    "! name~=''",
#    "name = 'Notification'",
#    "name = 'Plank'",
#    "name = 'Docky'",
#    "name = 'Kupfer'",
#    "name = 'xfce4-notifyd'",
#    "name *= 'VLC'",
#    "name *= 'compton'",
#    "name *= 'Chromium'",
#    "name *= 'Chrome'",
#    "name *= 'Firefox'",
#    "class_g = 'Conky'",
#    "class_g = 'Kupfer'",
#    "class_g = 'Synapse'",
#    "class_g ?= 'Notify-osd'",
#    "class_g ?= 'Cairo-dock'",
#    "class_g ?= 'Xfce4-notifyd'",
#    "class_g ?= 'Xfce4-power-manager'"
    "name = 'poniesbox'"
];
# Avoid drawing shadow on all shaped windows (see also: --detect-rounded-corners)
shadow-ignore-shaped = false;

#################################
#
# Opacity
#
#################################

menu-opacity = 1;
inactive-opacity = 1;
active-opacity = 1;
frame-opacity = 1;
inactive-opacity-override = false;
alpha-step = 0.06;

# Dim inactive windows. (0.0 - 1.0)
# inactive-dim = 0.2;
# Do not let dimness adjust based on window opacity.
# inactive-dim-fixed = true;
# Blur background of transparent windows. Bad performance with X Render backend. GLX backend is preferred.
#blur-kern = "7,7,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"
#blur-kern = "5,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"
##blur-kern = "3,3,1,1,1,1,1,1,1,1"
blur-background = false;
# Blur background of opaque windows with transparent frames as well.
blur-background-frame = false;
# Do not let blur radius adjust based on window opacity.
blur-background-fixed = false;
blur-background-exclude = [
    "window_type = 'dock'",
    "window_type = 'desktop'"
];

#################################
#
# Fading
#
#################################

# Fade windows during opacity changes.
fading = true;
# The time between steps in a fade in milliseconds. (default 10).
fade-delta = 4;
# Opacity change between steps while fading in. (default 0.028).
fade-in-step = 0.03;
# Opacity change between steps while fading out. (default 0.03).
fade-out-step = 0.03;
# Fade windows in/out when opening/closing
# no-fading-openclose = true;

# Specify a list of conditions of windows that should not be faded.
fade-exclude = [
    "name = 'poniesbox'"
];

#################################
#
# Other
#
#################################

# Try to detect WM windows and mark them as active.
mark-wmwin-focused = true;
# Mark all non-WM but override-redirect windows active (e.g. menus).
mark-ovredir-focused = true;
# Use EWMH _NET_WM_ACTIVE_WINDOW to determine which window is focused instead of using FocusIn/Out events.
# Usually more reliable but depends on a EWMH-compliant WM.
use-ewmh-active-win = true;
# Detect rounded corners and treat them as rectangular when --shadow-ignore-shaped is on.
detect-rounded-corners = true;

# Detect _NET_WM_OPACITY on client windows, useful for window managers not passing _NET_WM_OPACITY of client windows to frame windows.
# This prevents opacity being ignored for some apps.
# For example without this enabled my xfce4-notifyd is 100% opacity no matter what.
detect-client-opacity = true;

# Specify refresh rate of the screen.
# If not specified or 0, compton will try detecting this with X RandR extension.
refresh-rate = 60;

# Set VSync method. VSync methods currently available:
# none: No VSync
# drm: VSync with DRM_IOCTL_WAIT_VBLANK. May only work on some drivers.
# opengl: Try to VSync with SGI_video_sync OpenGL extension. Only work on some drivers.
# opengl-oml: Try to VSync with OML_sync_control OpenGL extension. Only work on some drivers.
# opengl-swc: Try to VSync with SGI_swap_control OpenGL extension. Only work on some drivers. Works only with GLX backend. Known to be most effective on many drivers. Does not actually control paint timing, only buffer swap is affected, so it doesn’t have the effect of --sw-opti unlike other methods. Experimental.
# opengl-mswc: Try to VSync with MESA_swap_control OpenGL extension. Basically the same as opengl-swc above, except the extension we use.
# (Note some VSync methods may not be enabled at compile time.)
vsync = "opengl-swc";

# Enable DBE painting mode, intended to use with VSync to (hopefully) eliminate tearing.
# Reported to have no effect, though.
dbe = false;
# Painting on X Composite overlay window. Recommended.
paint-on-overlay = true;

# Limit compton to repaint at most once every 1 / refresh_rate second to boost performance.
# This should not be used with --vsync drm/opengl/opengl-oml as they essentially does --sw-opti's job already,
# unless you wish to specify a lower refresh rate than the actual value.
sw-opti = false;

# Unredirect all windows if a full-screen opaque window is detected, to maximize performance for full-screen windows, like games.
# Known to cause flickering when redirecting/unredirecting windows.
# paint-on-overlay may make the flickering less obvious.
unredir-if-possible = true;

# Specify a list of conditions of windows that should always be considered focused.
focus-exclude = [ ];

# Use WM_TRANSIENT_FOR to group windows, and consider windows in the same group focused at the same time.
detect-transient = true;
# Use WM_CLIENT_LEADER to group windows, and consider windows in the same group focused at the same time.
# WM_TRANSIENT_FOR has higher priority if --detect-transient is enabled, too.
detect-client-leader = true;

#################################
#
# Window type settings
#
#################################

wintypes:
{
    tooltip =
    {
        # fade: Fade the particular type of windows.
        fade = true;
        # shadow: Give those windows shadow
        shadow = false;
        # opacity: Default opacity for the type of windows.
        opacity = 0.85;
        # focus: Whether to always consider windows of this type focused.
        focus = true;
    };
};

有时候我们想知道一个module安装到什么目录,如果使用ExtUtils::Installed进行查找的话,感觉非常慢。
后来想到一个hack的办法,从@INC所有目录中遍历检测对应的模块文件是否存在就行了,因此一行代码如下:

$perl -E 'say for grep {-f} map {"$_/IO/All.pm"} @INC'
/Library/Perl/5.16/IO/All.pm

轻松搞定。