TCP单边优化是CDN之大忌,但又不能不说。常规单边优化使能于作为发送端的CDN服务器,但对诸如客户端上传场景,此举便使不上力。怎么办?
可在接收端修改针对上传data之ack的时间戳,以减小发送端的rtt,最终减小其TLP,RTO,RACK等timer超时时间,目标是尽可能快速触发重传。做法简述如下。
- 当TCP发送端发送data,会做以下赋值:
data.TSval = $now + delta - 当TCP接收端对data回复ack,会做以下赋值:
ack.TSecr = data.TSval - 当TCP发送端收到ack,将计算瞬时iRTT:
iRTT = $now + delta - ack.TSecr - TCP发送端随即用iRTT计算sRTT以及各timer超时时间。
从以上过程可知,若增加ack.TSecr,则会减少iRTT,至于如何增加ack.TSecr以及增加多少,就是作为接收端的服务器上要做的。
为确保ack.TSecr不会超过发送端$now + delta,接收端需要知道实的sRTT,对于单向传输,rcv_rtt并不可信,需接收端主动发送携SYN标志的报文进行探测,依据如下:
RFC 5961 4.2: If the SYN bit is set, irrespective of the sequence number, TCP MUST send an ACK (also referred to as challenge ACK) to the remote peer.
记接收端所获RTT为rRTT,可按如下例子(1/4可调)计算并赋值:
ack.TSecr = data.TSval + 1/4*rRTT
如此便可成事。
此举对发送端的影响如下:
- 发送端运行Reno/BIC/CUBIC,对cc无影响,仅优化TLP/RTO/RACK。
- 发送端运行BBR,除优化TLP/RTO/RACK外,还可取消ProbeRTT避免inflight降为4,亦可影响minRTT采集时机,风险在于对cwnd影响属负向,当心cwnd limited。
- 发送端运行其它cc,未知。
对于Reno族(Reno/BIC/CUBIC),AIMD并不直接使用RTT数值,因此降低RTT对AI过程的cwnd无影响,但对于BBR,却有有趣的idea。
BBR(至少是Linux实现)并不以RTT参与计算delivery rate,而是自行打点,故改变RTT对采集delivery rate无影响,同时BBR采用minRTT计算BDP进而导出cwnd,故改变RTT可改变cwnd,前面描述了减少RTT则何如,却担心减少RTT会压缩cwnd,何不增大RTT,仅在两次或多次10s周期减小一次RTT帮发送端采集一次minRTT,此举既不影响发送端pacing rate计算,亦可在大多数情况下增其cwnd,不失为促进发送端激进传输的好方略。
此事既成,裂开一个新话题,稍微解释TCP时间戳的形式。
TCP时间戳使用各自独立的相对时间,且必要时加入对端并不知晓的delta,原因如下:
- 两端时间无需同步,各自即可计算RTT。
- 随机delta可避免对端猜测本端时间。
第一点明显摆脱了同步约束,着重解释第二点。
若直接取开机时间作时间戳,即便对端知道又如何?如何:
- 本机多久没有重启会暴露,期间若有内核安全更新,对端确知本机未patch。
- 本机角色会暴露,若开机180天,大概服务器,若不足一天,则为PC,手机亦可猜。
- 若为PC or手机,对端可探测主人生活习惯,譬如在午夜,在清晨。
- 哦…
so,针对每连接初始化不同的随机delta,目标是不和陌生人说话。
浙江温州皮鞋湿,下雨进水不会胖。