tm: don't reply if the reply dest. is not yet set
authorAndrei Pelinescu-Onciul <andrei@iptel.org>
Wed, 18 Aug 2010 16:39:43 +0000 (18:39 +0200)
committerAndrei Pelinescu-Onciul <andrei@iptel.org>
Wed, 18 Aug 2010 16:49:10 +0000 (18:49 +0200)
- relay_reply() doesn't attempt to send the reply if the reply
 destination is not yet fully set. This can happen for example
 if reply_to_via is set, Via contains a host name (and not an ip)
 and before having a chance to resolve the name a reply must be
 sent (reply for a message that hasn't been sent yet: very
 unlikely, but possible).

- use a membar_write() in init_rb(), before setting the reply send
  socket (the reply send socket is also used as a flag for a fully
  initialized reply destination and the membar_write() makes sure
  that everything else was written before the send socket and no
  re-ordering will take place).

modules/tm/t_lookup.c
modules/tm/t_reply.c

index b0ddfa6..e69fdec 100644 (file)
@@ -1196,7 +1196,6 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
        /*struct socket_info* send_sock;*/
        struct via_body* via;
        int proto;
-       int backup_mhomed;
 
        /* rb. timers are init. init_t()/new_cell() */
        via=msg->via1;
@@ -1220,20 +1219,8 @@ int init_rb( struct retr_buf *rb, struct sip_msg *msg)
        rb->dst.comp=via->comp_no;
 #endif
        rb->dst.send_flags=msg->rpl_send_flags;
-       /* turn off mhomed for generating replies -- they are ideally sent to where
-          request came from to make life with NATs and other beasts easier
-       */
-       backup_mhomed=mhomed;
-       mhomed=0;
-       mhomed=backup_mhomed;
-       /* use for sending replies the incoming interface of the request -bogdan */
-       /*send_sock=get_send_socket(msg, &rb->dst.to, proto);
-       if (send_sock==0) {
-               LOG(L_ERR, "ERROR: init_rb: cannot fwd to af %d, proto %d "
-                       "no socket\n", rb->dst.to.s.sa_family, proto);
-               ser_error=E_BAD_VIA;
-               return 0;
-       }*/
+       
+       membar_write();
        rb->dst.send_sock=msg->rcv.bind_address;
        return 1;
 }
index df372e1..1a90844 100644 (file)
@@ -637,7 +637,7 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
           If reply_to_via is set and via contains a host name (and not an ip)
           the chances for this increase a lot.
         */
-       if (!trans->uas.response.dst.send_sock) {
+       if (unlikely(!trans->uas.response.dst.send_sock)) {
                LOG(L_ERR, "ERROR: _reply_light: no resolved dst to send reply to\n");
        } else {
                if (likely(SEND_PR_BUFFER( rb, buf, len )>=0)){
@@ -1786,7 +1786,8 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
                if (reply_status == RPS_COMPLETED) {
                        start_final_repl_retr(t);
                }
-               if (SEND_PR_BUFFER( uas_rb, buf, res_len )>=0){
+               if (likely(uas_rb->dst.send_sock &&
+                                       SEND_PR_BUFFER( uas_rb, buf, res_len ) >= 0)){
                        if (unlikely(!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT))){
                                run_trans_callbacks( TMCB_RESPONSE_OUT, t, t->uas.request,
                                        relayed_msg, relayed_code);
@@ -1801,7 +1802,8 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
                                run_onsend_callbacks2(TMCB_RESPONSE_SENT, t, &onsend_params);
                        }
 #endif
-               }
+               } else if (unlikely(uas_rb->dst.send_sock == 0))
+                       ERR("no resolved dst to send reply to\n");
                /* Call put_on_wait() only if we really send out
                * the reply. It can happen that the reply has been already sent from
                * failure_route  or from a callback and the timer has been already