According to the TM reparse_invite option description Kamailio should build the CANCEL request from the INVITE message which was sent out instead of building them from the received request. And Kamailio does it for all headers except "To".
Kamailio builds "To" header from the received INVITE.
Patch to fix it:
--- ./kamailio-3.2.3/modules/tm/t_cancel.c 2012-08-22 10:39:21.000000000 +0300 +++ ./kamailio-3.2.3-fixed/modules/tm/t_cancel.c 2012-10-01 18:25:57.000000000 +0300 @@ -284,7 +284,7 @@ if (cfg_get(tm, tm_cfg, reparse_invite)) { /* build the CANCEL from the INVITE which was sent out */ cancel = build_local_reparse(t, branch, &len, CANCEL, CANCEL_LEN, - &t->to + NULL #ifdef CANCEL_REASON_SUPPORT , reason #endif /* CANCEL_REASON_SUPPORT */
It is not a problem when Kamailio doesn't change "To" header or does it before transaction creation (t_relay, t_newtran). To reproduce that situation "To" header should be rewritten in a branch_route.
build_local_reparse is also used in t_reply.c to build local ACK requests and passing new "To" header absolutely right there, since "To" header in ACK must be equal to "To" header field in the response being acknowledged. But if I correctly understand rfc3261 it is not correct behaviour for a CANCEL request.
P.S. I've checked 3.3.1 sources and haven't found any changes related to this issue.