I'm in the process of converting our proxy server to 3261 compliance, and I've run into a situation where I'm not sure what the correct thing is to do, algorithmically.
Specifically, I'm not sure when a proxy should forward an ACK message that's not associated with any transaction, and when it should just drop it. An ACK message which doesn't match an existing INVITE transaction, and which isn't addressed to a resource the proxy's responsible for, is presumably, if the sender is RFC-compliant, an end-to-end ACK. According to my reading of RFC 3261 section 16.5, it should just be forwarded, presumably statelessly since no responses are expected. However, my concern is that the sender might *not* be RFC-compliant; in particular, it might be hostile, and trying to use our proxy server to perform ACK-flood denial-of-service on some third party, or something. So I'd like some way to be sure that ACKs we forward are associated with INVITE transactions we actually accepted and forwarded in the past. For a UAS, associating an end-to-end ACK with its corresponding INVITE is reasonably straightforward. You find the dialog matching the ACK's dialog ID, and then within that dialog find the INVITE transaction whose CSeq matches the CSeq of the ACK. But this doesn't work for a proxy server, which might be stateless. (It also doesn't uniquely identify a proxy transaction if there's a spiral, but that doesn't matter for this purpose.) We need to consider: why would we, legitimately, receive the end-to-end ACK at a proxy server? There are two potential reasons. First of all, the proxy could have Record-Route'd. In this case, associating the ACK with the initial transaction is straightforward, in principle: the proxy can insert a transaction hash in a parameter of the Record-Route URI, so it'll be in the Route header it receives (or the request-URI if the upstream is a strict router). If this transaction hash is valid, it forwards the ACK; otherwise, it drops it. This should be correct even in the presence of Record-Route'd request spirals. Secondly, however, we could have a UAC using the proxy as an outbound proxy. In this case, it's possible that we don't insert a Record-Route header, not anticipating that we'll be doing anything that requires us to stay on the dialog path, but the UAC could send us the ACK anyway. If the initial INVITE was destined for a foreign location -- i.e., the UAC is using us as a true outbound proxy -- our proxy's current relay-denying policy is that it 407s the request and insists that the UAC provide credentials before it'll forward the request. In this case, 3261 says that the ensuing end-to-end ACK should carry the same credentials as the INVITE, so we can verify that, even if we can't necessarily associate the ACK with a specific INVITE transaction, we know that forwarding it statelessly is valid. However, it's also possible that a UAC is using us as an outbound proxy, but is also calling a local user. With our proxy, if a request's Request-URI points at a resource we handle, we don't normally challenge the INVITE (unless the target has an always-authenticate policy). However, the following flow can occur (assume the local domain is cs.columbia.edu): UAC -> Proxy INVITE sip:[EMAIL PROTECTED] SIP/2.0 Proxy -> downstream INVITE sip:[EMAIL PROTECTED] SIP/2.0 ... downstream -> Proxy 200 OK / Contact: <sip:device.somewhere.example> Proxy -> UAC 200 OK / Contact: <sip:device.somewhere.example> UAC -> Proxy ACK sip:device.somewhere.example SIP/2.0 What do we do with this ACK? It's not transactionally associated with the initial INVITE transaction, it's not directed at a URI we handle locally, it doesn't have any Route headers, and it doesn't carry any credentials. You can't respond to an ACK, so we can't send a 407 to get credentials. Yet clearly, from a big-picture point of view, we have to forward the ACK. So, I'm not sure what to do here. Unfortunately, there doesn't seem to be any way for a proxy to put a piece of information into a forwarded INVITE that it gets back in an end-to-end ACK, other than by Record-Routing or performing an authentication challenge. We can't trust either the From: address, or the source IP, of the ACK, since either one could be forged. We could just say in our documentation "if your proxy server is going to be used as an outbound proxy, you must enable Record-Route for all transactions". But that doesn't seem like a good idea. We could just not worry about it, and always statelessly proxy ACK messages, since there's no message traffic amplification (it's one message in -> one out), and no local state accumulation, so the use for denial-of-service is limited. But I'm nervous about this. So, any thoughts? -- Jonathan Lennox [EMAIL PROTECTED] _______________________________________________ Sip-implementors mailing list [EMAIL PROTECTED] http://lists.cs.columbia.edu/mailman/listinfo/sip-implementors
