The contact
usually is the IP address of the client. So, if you the SIP
server routes based on the contact header, it should send the INVITE
directly to the client not to the proxy. Somehow this all does not fit
together.
Clarification : Both clients A and B have the proxy as an outbound
proxy. Clients register to the SIP server through the proxy. The SIP
server routes the INVITE (INVITE from A that was proxied to SIP server)
to the proxy with the R-URI being constructed based on the contents of
the Contact header (IP only no port info). This is what I meant by
saying the SIP server routes INVITE based on registered Contact (R-URI
of INVITE is based on Contact header of client B's REGISTER message).
To me it seems that the SIP server also does some kind of NAT traversal:
it puts the Contact IP in to the RURI but it sends the request to the
IP:port from which the REGISTER was received (that's called NAT traversal).
So, either fix the SIP server (make sure it adds the port as in the
Contact header also to the RURI) or try a workaround:
A woraround would be for example to put the received port in the Contact
URI as an URI paramter. If the SIP server does not strip URI parameters
as well, then you might be lucky and restore the port from the parameter
in the RURI.
For the URI-parameter workaround try the functions
add_contact_alias() and handle_ruri_alias():