! \brief returns a socket_info pointer to the sending socket or 0 on error * \param msg SIP message (can be null) * \param to destination socket_union pointer * \param proto protocol * * \note if msg!=null and msg->force_send_socket, the force_send_socket will be used */
| 143 | * \note if msg!=null and msg->force_send_socket, the force_send_socket will be used |
| 144 | */ |
| 145 | const struct socket_info* get_send_socket(struct sip_msg *msg, |
| 146 | const union sockaddr_union* to, int proto) |
| 147 | { |
| 148 | const struct socket_info* send_sock, *bond_sock; |
| 149 | struct socket_info_ref *bond_ref; |
| 150 | |
| 151 | /* check if send interface is not forced */ |
| 152 | if (msg && msg->force_send_socket){ |
| 153 | if (msg->force_send_socket->proto == PROTO_BOND) { |
| 154 | |
| 155 | bond_sock = msg->force_send_socket; |
| 156 | msg->force_send_socket = NULL; |
| 157 | for (bond_ref = bond_sock->bond_sis; |
| 158 | bond_ref; bond_ref = bond_ref->next) { |
| 159 | |
| 160 | LM_DBG("checking socket [%.*s]:%d AF %d for " |
| 161 | "destination proto=%d and AF=%d\n", |
| 162 | bond_ref->si->sock_str.len, bond_ref->si->sock_str.s, |
| 163 | bond_ref->si->proto, bond_ref->si->address.af, |
| 164 | proto, to->s.sa_family); |
| 165 | if (!bond_ref->si || |
| 166 | (bond_ref->si->proto != proto) || |
| 167 | (bond_ref->si->address.af != to->s.sa_family)) |
| 168 | continue; |
| 169 | |
| 170 | msg->force_send_socket = bond_ref->si; |
| 171 | LM_DBG("bond socket [%.*s] translated into [%.*s] for " |
| 172 | "destination proto=%d and AF=%d\n", |
| 173 | bond_sock->name.len, bond_sock->name.s, |
| 174 | bond_ref->si->sock_str.len, bond_ref->si->sock_str.s, |
| 175 | proto, to->s.sa_family); |
| 176 | break; |
| 177 | } |
| 178 | |
| 179 | if (!msg->force_send_socket) |
| 180 | LM_DBG("no bond member matching proto=%d and AF=%d\n", |
| 181 | proto, to->s.sa_family); |
| 182 | } else |
| 183 | /* no bond forced socket, do extra checks */ |
| 184 | if (msg->force_send_socket->proto!=proto){ |
| 185 | LM_DBG("force_send_socket of different proto (%d)!\n", proto); |
| 186 | msg->force_send_socket=find_si(&(msg->force_send_socket->address), |
| 187 | msg->force_send_socket->port_no, |
| 188 | proto); |
| 189 | } else |
| 190 | if (msg->force_send_socket->address.af!=to->s.sa_family){ |
| 191 | LM_DBG("force_send_socket of different AF (sock=%d, dst=%d)!\n", |
| 192 | msg->force_send_socket->address.af, to->s.sa_family); |
| 193 | msg->force_send_socket=NULL; |
| 194 | } else |
| 195 | if (msg->force_send_socket) |
| 196 | return msg->force_send_socket; |
| 197 | else |
| 198 | LM_WARN("protocol/port/af mismatch\n"); |
| 199 | }; |
| 200 | |
| 201 | if (mhomed && proto==PROTO_UDP) |
| 202 | return get_out_socket(to, proto); |
no test coverage detected