Categories
生活琐碎

病了一场

昨晚上怕冷怕的要死,盖了被子还觉得冷
早上睡醒又热的要命,感觉人要烧起来了
请了个病假,医院折腾一天,现在仍旧腰酸背疼加头痛
还是身体最要紧,不然什么事情都做不了

Categories
不学无术

RFC1928 SOCKS5协议 – 部分内容翻译

Reference: https://www.ietf.org/rfc/rfc1928.txt
只是部分章节的翻译


3. TCP客户端的连接流程

当某一基于TCP的客户端想要经由防火墙(取决于具体实现)与远端对象建立连接时,它必须首先开启与SOCKS服务器上对应端口的TCP连接。通常情况下SOCKS服务器监听的TCP端口号是1080. 若连接请求成功,客户端将进入授权模式协商阶段,随后使用所选的模式进行授权,继而开始连接。SOCKS服务器对请求进行评估,继而建立指定的连接或拒绝连接。
除非另有说明,下文数据报中提及的十进制数字均为对应字段的字节长度。当某个字节必须是一个具体数值时,以X’hh’来表示这一字段的具体值。当使用’Variable'(可变长)时,表示这一字段拥有可变长度的内容,具体长度通过一个关联的长度字段表示,或根据某钟具体的数据类型字段决定。
客户端连接至服务器并发送一个标识符/方法选择信息:

                   +----+----------+----------+
                   |VER | NMETHODS | METHODS  |
                   +----+----------+----------+
                   | 1  |    1     | 1 to 255 |
                   +----+----------+----------+

其中,字段VER设置为X’05’以表明此协议的版本。NMETHODS字段包含了METHODS字段中所填鉴权方法(method)的个数,以字节为长度单位——METHODS中的一个方法标识符占一个字节。
服务器从METHODS给定的方法中选择一种,回传一个方法选择消息:

                         +----+--------+
                         |VER | METHOD |
                         +----+--------+
                         | 1  |   1    |
                         +----+--------+

如果选择的方法值为X’FF’,则表明服务器不接受客户端能提供的任一种鉴权方法,客户端必须在收到此消息后断开连接。
METHOD中可以定义的方法为:

  • X’00’ 无需鉴权方法
  • X’01’ GSSAPI
  • X’02’ 用户名/密码
  • X’03’ 至 X’7F’ IANA指定
  • X’80’ 至 X’FE’ 私有方法保留
  • X’FF’ 没有可接受的方法

随后,服务器与客户端进入协议特定的子协商(sub-negotiation)阶段。
协议特定的子协商过程在描述于不同备忘录中。
本协议新方法的开发人员必须向IANA申请一个新的METHOD号……(省略两段合规相关的话)

4. 请求(Requests)

一旦完成了协议特定的子协商过程,客户端便发送请求细节。如果方法的协商包括了完整性检查或保密相关的封装,那么这些请求必须以指定方式进行相同的封装。
SOCKS的请求,其格式如下:

        +----+-----+-------+------+----------+----------+
        |VER | CMD |  RSV  | ATYP | DST.ADDR | DST.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

其中:

  • VER: 协议版本号:X’05’
  • CMD
    • CONNECT X’01’
    • BIND X’02’
    • UDP ASSOCIATE X’03’
  • RSV 保留字段
  • ATYP 地址类型
    • IP V4 地址: X’01’
    • 域名: X’03’
    • IP V6 地址: X’04’
  • DST.ADDR 期望的目标地址
  • DST.PORT 期望的目标端口号,以网络字节序表示

5. 地址(Addressing)

一个地址字段(DST.ADDR, BND.ADDR)的具体类型由ATYP字段的值来表示:

  • X’01’ 为4个字节表示的IPV4地址
  • X’03’ 表示一个域名,地址字段中的第一个字节表示后续字符的总长度(字节数),地址字段不包含NUL结束符
  • X’04’ 为16字节表示的IPV6地址

6. 回复(Replies)

一旦SOCKS客户端与服务器建立连接,SOCKS请求即被发送,随即进行鉴权方式的协商。服务器端对请求进行识别,并以下属形式回复:

        +----+-----+-------+------+----------+----------+
        |VER | REP |  RSV  | ATYP | BND.ADDR | BND.PORT |
        +----+-----+-------+------+----------+----------+
        | 1  |  1  | X'00' |  1   | Variable |    2     |
        +----+-----+-------+------+----------+----------+

其中:

  • VER:协议版本号: X’05’
  • REP:回复字段:
    • X’00’ 成功
    • X’01’ 一般SOCKS服务器错误
    • X’02’ 规则集(ruleset)不允许该连接
    • X’03’ 网络不可用
    • X’04’ 主机不可达
    • X’05’ 连接被拒绝
    • X’06’ TTL超时
    • X’07’ 不支持该命令
    • X’08’ 不支持该地址类型
    • X’09’ 至 X’FF’ 尚未指定
  • RSV:保留字段
  • ATYP:后续地址的类型
    • IPV4地址: X’01’
    • 域名:X’03’
    • IPV6地址: X’04’
  • BND.ADDR: 服务器绑定地址
  • BND.PORT:服务器绑定端口号,网络字节序表示

CONNECT

对CONNECT(连接)请求的回复中,BND.PORT包含服务器指派的用于连接远程主机的端口号,BND.ADDR为对应的IP地址。指派的BND.ADDR通常与客户端请求的目标地址不同,因为目标主机可能拥有多组地址(multi-homed)。预期情况下SOCKS服务器使用DST.ADDR与DST.PORT,连同客户端的地址、端口号,一起确定一个CONNECT请求。

BIND

BIND(绑定)请求通常用在那些客户端需要接受(accept)服务器连接的协议中。FTP便是一个令人熟知的例子,它主要使用客户端->服务器连接来发送命令、报告状态,但同时也会用服务器->客户端连接来传输数据(e.g. LS, GET, PUT)。
预期情况下,客户端一侧的应用协议仅在使用过CONNECT请求完成一个主连接的情况下,再使用BIND请求请求一个二次连接。预期情况下SOCKS服务器使用DST.ADDR与DST.PORT来确定一个BIND请求。
在一次BIND操作过程中,SOCKS服务器将给客户端回复两条消息。第一条将会在服务器建立连接并绑定一个新的socket口时发送。BND.PORT字段包含了一个端口号,该端口号是SOCKS服务器指派的用于接收传入连接的。BND.ADDR包含了对应的IP地址。通常情况下,客户端根据这些信息来通知(经由主连接)应用程序服务器(目标主机)这一地址的存在。第二次应答只发生与预期的传入连接成功或失败发生时。在二次应答中,BND.PORT及BND.ADDR字段包含了目标主机(connecting host)的地址和端口号。

UDP ASSOCIATE

UDP ASSOCIATE请求用作UDP中继过程中建立关联以处理UDP数据报文。DST.ADDR和DST.PORT字段包含了客户端期望关联的,用于发送UDP数据报的目标地址及端口号。服务器或能使用这一信息来限制连接请求。如果客户端在UDP ASSOCIATE阶段尚不能拥有这些信息,则它必须使用全零的端口号及地址。
当UDP ASSOCIATE请求到达的TCP连接终止时,UDP关联终止。
在对UDP ASSOCIATE请求的应答中,BND.PORT和BND.ADDR字段表明了客户端必须发送UDP中继请求的端口号/地址。

应答处理

当应答失败时(REP值不等于X’00’),SOCKS服务器必须在发送应答消息后立即关闭TCP连接。这一操作必须在检测到异常状态后不超过10秒时执行。
如果应答码标识为成功(REP==X’00’),并且请求既不是BIND也不是CONNECT,则客户端可以开始传输数据。如果协商的传输方式包含对于数据完整性,鉴权或保密性的封装要求,其传输的数据也应按此要求封装。类似操作也许是实施于反向的传输过程中。

7. UDP客户端的操作

一个UDP客户端必须将自己的数据报发送至指定的UDP中继服务器,其端口号是在UDP ASSOCIATE应答中由BND.PORT字段指定的端口号。其数据报中鉴权、一致性及加密性封装必须与协商时表明的相同。每个UDP数据报包含一个UDP请求头:

      +----+------+------+----------+----------+----------+
      |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
      +----+------+------+----------+----------+----------+
      | 2  |  1   |  1   | Variable |    2     | Variable |
      +----+------+------+----------+----------+----------+

该请求头中包含的字段为:

  • RSV:保留字段 X’0000′
  • FRAG:当前分段号
  • ATYP:下述地址类型:
    • IPV4地址: X’01’
    • 域名:X’03’
    • IPV6地址:X’04’
  • DST.ADDR:期望的目标地址
  • DST.PORT:期望的目标端口号
  • DATA:用户数据

当一个UDP中继服务器决定中继一个UDP数据报时,它静默地执行上述操作,不通知任何客户端。类似的,它会丢弃它无法中继的数据报。当一个UDP中继服务器收到远程主机传来的应答数据报时,它必须使用上述报头格式封装数据报,若有必要同时将依据之前协商的鉴权方法再封装。
UDP中继服务器必须从SOCKS服务器中获取客户端期望发送数据报的IP地址,客户端用该地址加上UDP ASSOCIATE应答中提及的BND.PORT来发送数据报。它必须丢弃任何在关联之外的,从源IP地址传输过来的数据报。
FRAG字段表明了这个数据报是不是数据报段中的一部分。如果分段实施,则最高阶的位(bit)表明是否分段结束,值X’00’表明这是个独立的数据报。在1与127之间的数值表明这个数据报在分段中的顺序。每个接收者必须实现一个与之关联的REASSEMBLY QUEUE(重组队列)与REASSEMBLY TIMER(重组计时器)。重组队列必须在计时器超时时,亦或是传入数据报FRAG字段值小于当前最大字段值时,丢弃那些尚未组合成功的数据报,并且重新初始化。重组计时器必须设置不超过5秒的超时值。一般建议,只要条件允许,不启用分段。
分段的实施时可选的;一个不允许分段操作的实现,它必须丢弃任何FRAG值不为X’00’的任何数据报。
一个SOCKS-可感知的UDP程序接口必须报告一个可用的UDP数据报缓存长度,且其必须小于操作系统允许的空间:

  • 若ATYP==X’01’  < 10 + method_dependent 字节
  • 若ATYP==X’03’ : < 262 + method_dependent 字节
  • 若ATYP==X’04’ : < 20 +  method_dependent 字节

 

Categories
不学无术

Basic Risks on Options 期权的基本风险类型

书里看到的,摘记一下。

  • Delta (Directional) Risk. Underlying的价格向某一侧移动的风险,主要做法是构造delta中性的position;
  • Gamma (Curvature) Risk. Underlying价格发生大幅波动的风险,这种风险并非是delta那种方向性的。承受这种风险的position是Gamma为负数的那些期权,因为由定义可以推出来,+Gamma的那些期权,在价格发生波动时其价值反而会增加;
  • Theta (Time Decay) Risk. 与Gamma风险是反向的一对,能通过Gamma获得价值的期权,他们的价值随着时间而逝去…
  • Vega (Volatility) Risk. 我们给模型输入的那个volatility可能是错的,错误的输入将得到错误的模型(概率分布),产生错误的结果;或者,期权市场自身的变化导致的隐含波动率的改变;
  • Rho (Interest-Rate) Risk. 期权有效期内利率的变化对其价值的影响。Rho>0说明利率上升能增加期权的价值,反之亦然。但通常而言,这个风险应当是在前面几种风险之后才考虑的;

 

Categories
不学无术

Volatility Spreads – Two General Guidance

Here I excerpt two useful sections in Chapter 12 of the book Option Volatility & Pricing.

Choosing an Appropriate Strategy

If implied volatility is low, such that options generally appear underpriced, look for spreads with a positive vega. If implied volatility is high, such that options generally appear overpriced, look for spreads with a negative vega.

 

Long calendar spreads are likely to be profitable when implied volatility is low but is expected to rise; short calendar spreads are likely to be profitable when implied volatility is high but is expected to fall.

Categories
不学无术

Risk Measurement I (the Greeks,希腊值)

希腊值(The Greeks)是期权或衍生品定价用的比较重要的指标,简单来说有了希腊值以后可以拿到某个产品的理论价格(theo),有了理论价格我们就有了交易的方向了。
目前常用的希腊值有下面几种:

  • Delta (Δ):measure of an option’s risk with respect to the direction of movement in the underlying contract. 通俗的讲就是标的物(underlying)的价值变化1个单位的话,期权的价格相应地也会变化Δ,当然这里的“变化”是有方向的,这个取决于期权的性质(call, put)以及当时的其他情况;如果以underlying的价值为横轴,option的价值为纵轴,那delta值就是所对应曲线的斜率。还有另一种解释,如果不管Δ的正负号的话,即|Δ|其实是约等于所对应期权最后成为实值期权(in-the-money)的概率

    有一个种基础的对冲方法就叫Δ对冲(delta hedging)。
  • Gamma(Γ): 是Δ的变化与underlying价格的变化率,或者说underlying价格变化1个单位,Δ会变化多少。当我们买入期权时,就构造了+Γ值;反之卖出期权时-Γ。如果Δ看做“速度”的话,那Γ就是“加速度”了。
  • Theta(Θ): 反映时间流逝带来的期权价格变化。这个值基本是负数。
  • Vega(Κ):因为没有对应的希腊字母,所以用Kappa代替了。这个是波动率变化对期权理论价值的影响。举个例子,如果一个期权Κ=0.15,那么波动率每±1%,期权的理论价相应地会±0.15。
  • Rho(Ρ): 期权的理论价对利率变动的敏感程度。 这个值对于定价模型的影响是这几个希腊值里最小的,一般不用强调或者直接忽略这个变化。

下面总结一下各个希腊值头寸(position)与期权买卖的关系,方便起见直接用英文了:

-------------------------------------------------------------------
If you are...   |  Δ pos. |  Γ pos. |  Θ pos. |  Κ pos. |  Ρ pos.
-------------------------------------------------------------------
Long the under- |   +     |    0    |    0    |    0    |    0
lying contract  |         |         |         |         |
-------------------------------------------------------------------
Short the under |   +     |    0    |    0    |    0    |    0
lying contract  |         |         |         |         |
-------------------------------------------------------------------
Long Calls      |   +     |    +    |    -    |    +    | + S
                |         |         |         |         | - F
-------------------------------------------------------------------
Short Calls     |   -     |    -    |    +    |    -    | - S
                |         |         |         |         | + F
-------------------------------------------------------------------
Long Puts       |   -     |    +    |    -    |    +    | - S
                |         |         |         |         | - F
-------------------------------------------------------------------
Short Puts      |   +     |    -    |    +    |    -    | - S
                |         |         |         |         | + F
-------------------------------------------------------------------
-/+ S = -/+ on Stocks
-/+ F = -/+ on Futures

很显然的是,Long和Short是一对,符号全是反向的。
本文内容来自一本很不错的书:《Option Volatility and Pricing (Second Edition)》

Categories
不学无术

C++堆内存相关问题小结

C++中遇到的堆内存相关问题,基本可以归为下述三类:

  • 野指针
    • 一些内存单元已被释放,之前指向它的指针还在被使用。这会导致无法预测的运行时错误。
  • 重复释放
    • 试图释放已经被释放过的内存单元,或者释放已被重新分配的内存单元。这会导致运行时错误。
  • 内存泄漏
    • 不再需要的内存单元一直驻留没有释放。这会导致内存占用剧增,直至堆内存无法分配,运行时错误。

 
 
摘自《深入理解C++11》

Categories
生活琐碎

日淘ThinkPad X1 carbon 2017到手,写个下单转运收货流水账

2017.10 很不幸的事情发生了。去德国旅游的过程中,此电脑于柏林火车站附近在租的车子内被盗,怀疑是借助工具将车干扰解锁了——从此对柏林毫无好感,因为接警的警察都毫无诚意。Unfortunately this computer was stolen in Berlin, Germany during a trip. The local police seemed quite accustomed to this kind of case report and asked me to wait two hours in the night to create a case. It SUCKS!

 
笔记本终于到手了,来发下经历。

付款:
淘宝上找日本代购代付款的,他们好像是用银行转账的模式(并不是信用卡在线支付)。因此其实是我在日本官网定制->提供转账代码给代购->代购帮忙付款->发到我的转运仓库这一模式。需要注意的是,我找的代付其实并不比专门thinkpad代购的商家便宜,估计多了个运费钱的样子,不过因为好奇所以还是这么做了。
生产:
世界上最遥远的距离就是,电脑在中国生产,然后发到日本,然后又发回中国。
下单日期是2月28日,生产完毕到了3月6日左右,然后发到日本。日本进口是用NEC 日通的清关,清关完毕后日本国内走的宅急送派送,宅急送派件是第二天就到了转运仓库。由于留的自己的邮箱地址,在收到付款、准备生产、生产结束、转国内发货这些关键节点都能收到邮件,而且有官网可以实时查信息。
但是这里留下了一个大教训:走转运的亲,如果转运的客户识别号比较长的话,可能在联想订单的运单上就会被截断(鄙人血淋淋的教训)!因此建议选用XX四方这样把识别号体现在收件人姓名上的转运公司,我用JPDeliver的话客户代码有8位而且只有地址上有,今天拿到快递一看,被截断到了只有一位。
转运:
由于周末入库+客户代码被截断的问题,周一找客服翻仓库1小时才得以入库。也幸好是找到了,不然就坑了。
转运走的EMS,主要是能保价。整箱重3250g左右,联想的包装已经很好了,我没有选择任何额外加固。
由于有个同事走的必税天堂杭州入关,被税了15%(申报价值4K多,收了650+),果断找帝都朋友代收。3月14日日本寄出(申报价值7W 日元哈哈),17日无税到手(据说帝都不是0就是300,没有见过15%的)。以后万一出毛病了就找同事的税单吧哈哈
(技巧:EMS官网状态更新很慢,建议去http://www.fjxmems.com/查,还能看到些许内网信息,而且免费,不必淘宝上花钱查的差!)
然后17日顺丰陆运发到杭州,今天下午拿到。
基本体验:
配置: i7-7500U, 16G, 256G nvme,英文键盘
跟我的XPS13差不多轻,但是屏幕变大了而且窄边框,感觉很开心。屏幕分辨率的问题,目前用100%字少许有点小,125%小部分软件的字有点糊,据说win10即将到来的更新都强制GDI渲染了,可能可以根治…另外,新款用了USB-C的电源口,我看电源适配器上写着这么些参数,感觉都能用大一点的移动电源给电脑充电了(还是我火星了)?
(输出:20V 2.25A / 15V 3A / 9V 2A / 5V2A)
出风口在右边,不过目前没有感觉到有风,Intel虽是牙膏厂,但是还是厉害。
但是,触摸的体验(我不确定是硬件还是软件)虽有改进但还是不及macbook pro。

Categories
不学无术

C++11 继承构造函数、委派构造函数

C++11标准中引入了两种构造函数的活用方法,可以适当地减轻一些情景下的码字负担。

1.继承构造函数

以往情况下,在派生类中调用基类的构造函数,一般需要在派生类中显式调用:

struct A
{
    A(int i) {}
};
struct B
{
    B(int i) : A(i) {}
};

当构造函数的花式(签名)很多的时候,继承类写起来就比较辛苦了。
在C++11标准中,可以通过using声明来简化这种操作(using声明在以前的标准中已经可以用在非构造函数里)

struct A
{
    A(int i) {}
    A(double d, int i) {}
    A(float f, double d, int i) {}
    //...
};
struct B
{
    using A::A;    //继承构造函数
    //...
};

需要注意的是,采用这种using声明有两个规矩:

  • 如果基类的构造函数是private或是派生类是从基类中虚继承的,不能用这种方法;
  • 一旦用了继承构造函数,编译器就不会为派生类生成默认构造函数(Visual Studio报error C2280),除非基类自己没有定义任何构造函数而触发了默认构造函数生成;

2.委派构造函数

委派构造函数常用在减少初始化过程的代码冗余问题,比如下面这个经典例子(我就这么干过):

class Info
{
public:
    Info() { InitRest(); }
    Info(int i) : type(i) { InitRest(); }
    Info(char c) : name(c) { InitRest();}
private:
    void InitRest ()
    {
        // 初始化其他东西
    }
    int type {1};
    char name {'a'};
    //...
};

使用一般方法,我们无法在自己构造函数里又调用自己的构造函数(突然想起了python的import this,哈哈),纵使函数签名不同也会报编译错误。
C++11中,可以这么写:

class Info
{
public:
    Info() { InitRest(); }
    Info(int i) : Info() { type = i; }
    Info(char c) : Info() { name = c; }
private:
    void InitRest ()
    {
        // 初始化其他东西
    }
    int type {1};
    char name {'a'};
    //...
};

但是要注意,委派构造函数不能和初始化列表并用,不然依旧编译错误。
比如我们不能搞Info(int i) : Info(), type(i) { } 。
不过有解决办法,比如可以声明一个私有的构造函数,它包括“完整”的参数输入,然后公有的其他构造函数调用它:

class Info
{
public:
    Info() : Info(1, 'a') { } // 或采用链状委派: Info(1) 或 Info('a')
    Info(int i) : Info(i, 'a') { }
    Info(char c) : Info(1, c) { }
private:
    Info(int i, char e) : type(i), name(c) { }
    int type {1};
    char name {'a'};
    //...
};

关于函数执行顺序,目标函数执行总是先于委派构造函数的。

参考文献

《深入理解C++11 (C++11新特性解析与应用)》

Categories
未分类

人生哲理

除非你能忽视周遭环境,做你承诺过要做的事,否则你就会永远受到这个世界的控制。
——《肠子》恰克·帕拉尼克

Categories
生活琐碎

WoSign/StartCom的HTTPS证书风波

之前网站使用的StartCom发的SSL证书,结果今天登陆发现提示“不安全的网站”,一时费解去查了一下。原来这两家(一家)公司违反了证书签发规定,已经被好几个浏览器给墙了(详见https://linux.cn/article-7922-1.html)…
还好现在免费SSL证书比较多,换了家腾讯云旗下的TrustAsia之类的,终于又恢复了正常。