Via头域是标志了用于事务传输的传输设备,并且也标志了应答送回的地址。只有当需要通过选择传输设备到达下一个节点(hop)的时候,才需要在头域中包含Via域。当UAC创建一个请求,它必须在头域中添加一个Via域。protocol 名字和protocol版本必须分别是SIP和2.0。Via头域必须包含一个branch参数。这个参数用于区分请求创建的事务。这个参数客户端和服务器都会使用。除了CANCEL和给非2xx应答的ACK以外,branch参数对UA发出的所有的请求来说,在时间和空间上必须唯一。CANCEL请求的branch参数必须和他所取消的请求的branch参数一致。并且非2xxx(non-2xx)应答的ACK必须和其对应的的INVITE请求有相同的branch ID。
利用branch ID参数的唯一性,来作为事务的ID(transaction ID),并非RFC 2543的一部分。根据本标准产生的branch ID必须用“z9h64bK”开头。这7个字母是一个乱数cookie(定义成为7位的是为了保证旧版本的RFC2543实现不会产生这样的值),这样服务器收到请求之后,可以很方便的知道这个branch ID是否由本规范所产生的(就是说,全局唯一的)。在这样的要求下,精确的branch ID的格式必须事先有实现的定义。
proxy必须在请求的拷贝中增加一个Via头域值,并且在其他Via头域值之前增加。这意味着proxy需要计算自己的分支参数,并且应当是全局唯一的分支。注意这意味着如果请求循环经过本proxy的时候(也就是数次经过同一个proxy),每次的分支参数都不同。
在proxy构造分支参数的值上,有一个附加的约束,用来进行循环的检测。一个要检测循环的proxy应当创建一个由两部分组成的分支参数。第一部分必须满足以上的约束。第二部分是用来做循环检测的,并且是从螺旋中判定是否存在循环(请求数次经过同一个proxy是正常的,这是螺旋,但是如果是循环,那就不正常了。假定proxy是X,C-X,X-Y,Y-Z,Z-X,X-A,A目的地是正常的,但是如果C-X, X-Y, Y-Z, Z-X, X-Y, 这就是循环了)。
循环检测是通过这样的方法检测的:当请求返回给一个proxy,与处理请求相关的字段并未改变,那么这个就是循环了。这个分支参数的后一部分应当反应所有的这些头域(包括所有的Route,Proxy-Require和Proxy-Authorization头域)。这是确保如果请求从别处重新路由回来,而且这些字段改变了,那么这就是一个螺旋而不是循环。通常建立这个比较值的方法是计算一个hash值,通过基于To tag,From tag,Call-ID头域,收到请求的Request-URI(而不是经过处理过后的Request-URI),Via头域的最上一个,Cseq头域的序列号,任何附加的Proxy-Require或者Proxy-Authorization头域。具体的hash算法是基于实现相关的,但是MD5,用16进制表达,是一个有道理的选择。(基于64位表达的是不太合适的)。
如果proxy希望检测循环,那么“branch”参数必须用包含可能影响处理请求的全部信息构成,包括输入的Request-URI和其他可能会影响proxy处理路由的字段,通过计算得到。这是检测循环所必须的,因为如果请求在路由相关的字段改变以后,重新发回这个服务器,那么新的处理可能会发送到另外的地方,而不是造成一个循环。
在branch参数的计算上,请求的方法不能计算进去。但是作为特例,CANCEL和ACK请求(给非2xx应答的)必须和他们对应的请求有相同的branch值。branch参数用于在服务器处理这些请求的时候体现请求之间的相关性。