摘要

  • 在 RFC 2446 — iCalendar Transport-Independent Interoperability Protocol (iTIP) 的模型里,Attendee 发送的 COUNTER 是对既有安排的替代提议,即使其中带有完整 VEVENT 或 VTODO,也不会自行改写 Organizer 控制的主条目。
  • Organizer 对 COUNTER 的接受或拒绝是一层决策;接受之后重新安排并向受影响参会者发送新的 REQUEST,则是另一层独立状态转换。SEQUENCE、PARTSTAT、传输认证、本地日历状态和现实出席必须分别观察,不能互相替代。

1998 年 11 月发布的 RFC 2446 把日历安排写成一组与具体传输机制分离的事务。它建立在 RFC 2445 — Internet Calendaring and Scheduling Core Object Specification (iCalendar) 定义的数据对象和属性之上,而把“谁向谁发送什么 METHOD、接收方应如何处理”提升成协议问题。邮件绑定随后由 RFC 2447 — iCalendar Message-Based Interoperability Protocol (iMIP) 给出;后来 RFC 5546 — iCalendar Transport-Independent Interoperability Protocol (iTIP) 取代 RFC 2446,RFC 6047 — iCalendar Message-Based Interoperability Protocol (iMIP) 更新邮件传输绑定。

iTIP 的关键不是“一个日历对象有多完整”,而是谁拥有哪一层状态。Organizer 发起安排交换并创建、维护共享意义上的主条目;受邀用户则是 Attendee。这里的协议角色不能与 ATTENDEE 属性中的 ROLE 参数混为一谈:后者描述参与角色,前者决定协议流程中的权限和动作边界。

因此,周一会议的例子不能把 COUNTER 理解成远程编辑。按照 RFC 2446,PUBLISH 用于发布信息而不期待交互回复;REQUEST 要求接收者处理安排并允许其响应;REPLY 传达参会者自己的状态;COUNTER 提出对现有安排的修改;DECLINECOUNTER 则给 Organizer 一个明确拒绝该替代方案的机制。一个 COUNTER 可以包含完整的备用 VEVENT 或 VTODO,但“完整”只是消息表达完整,并不意味着替代对象自动成为新的组织者主条目。

如果 Organizer 接受“改到周二”的提议,协议上的下一步不是把收到的 COUNTER 当成既成事实,而是由 Organizer 形成自己的修订,并对受影响的参会者发送新的 REQUEST。RFC 5546 保留了这一机制,并明确建议组织者客户端在接受 COUNTER 后发送 REQUEST。于是,“参会者提出周二”“组织者接受周二”“组织者发布新的周二安排”属于不同动作,不能压缩成一个“已改期”状态。

SEQUENCE 更能说明这种分层。它追踪的是由 Organizer 主导的修订序列,不是共识计数器,也不是参会者同意的证明。在 RFC 2446 的规则下,REPLY、REFRESH、COUNTER、DECLINECOUNTER,以及委派流程中的 REQUEST,并不会因为这些消息本身而增加组织者事件的 SEQUENCE;ADD 与 CANCEL 则属于会推动相应修订语义的操作。参会者的回复还可能针对较早的组织者修订版本,因此仅看到一个 REPLY,不能推出所有参与方已经在同一版本上收敛。

类似边界也出现在邀请转发。参会者把邀请转发给原本未受邀的人,并不会自动把后者写进 Organizer 的主参会者列表。是否纳入仍由 Organizer 决定;转发者也不能借转发修改事件属性。这再次表明 iTIP 并不是让所有消息发送者共享对主记录的同等写权限,而是围绕不同角色配置不同的动作。

传输顺序还会打破人们对“时间先后”的直觉。store-and-forward 系统可能让 CANCEL 比原始 REQUEST 更早到达。RFC 2446 因而建议,对尚未找到关联对象且 SEQUENCE 非零的 CANCEL,可以暂存并等待较低序列的相关消息,也允许在等待超时后处理。这种规则解决的是乱序交付,不应被解释成已经证明所有副本最终一致。

安全层同样不能从日历字段里推导。RFC 2446 明确指出,Organizer 或 Attendee 身份都可能在消息中被伪造;身份认证、完整性和加密应由传输绑定提供。邮件环境下,这类保护可借助 MIME 安全机制,例如 RFC 1847 — Security Multiparts for MIME: Multipart/Signed and Multipart/Encrypted,但“有一个 ORGANIZER 字段”本身并不是认证。

由此也能得到一组重要的否定结论。成功解析一个 COUNTER,只说明对象可解析;较高 SEQUENCE 说明组织者修订顺序,而不是授权;送达回执说明某种传输结果,不说明接收者接受;REPLY 表示参会者状态,而不是现实出席;本地“已接受”一行、提醒弹窗或可见日历格,也都不能单独证明 Organizer 已授权、所有副本已经收敛,或者会议最终真的发生。

研究和监测 iTIP 时,因此至少要分开记录:原始消息、经过认证的发送者及其授权、METHOD 与 UID、Organizer 的 SEQUENCE、每个 Attendee 的 PARTSTAT、COUNTER 内容、Organizer 的决定、随后新的 REQUEST、传输接收、本地提交、提醒状态,以及现实中可观察到的出席。把这些层合并,会把“协议允许”“消息有效”“传输可信”“本地已写入”和“现实已发生”错误地压成同一个事实。

Heng Lu 的文章在这里更适合作为分析透镜,而不是 iTIP 的规范来源:规范文本、角色权限、经过认证的传输、软件实现、本地状态和现实结果应彼此分离。有效语法或规范发布本身,也不能证明真实部署、采用、同意或运行结果。对于 iTIP,激励边界尤其清楚:Attendee 有动力提出适合自己的替代时间;Organizer 控制共享主日历及是否重排;每个 Attendee 控制自己的回复;传输层负责帮助证明消息究竟来自谁。RFC 2446 的历史价值,正是在这些边界之间建立了可以逐步验证的状态转换,而不是让一条看起来完整的消息自动获得超出其角色的权力。

来源