! \brief * * \param send_sock = 0 if already known (e.g. for udp in some cases), * non-0 otherwise * \param proto =TCP|UDP * \param to = sockaddr-like description of the destination * \param id - only used on tcp, it will force sending on connection "id" * if id!=0 and the connection exists, else it will send to "to" * (useful for sending replies on the same connect
| 88 | * \return 0 if ok, -1 on error |
| 89 | */ |
| 90 | static inline int msg_send( const struct socket_info* send_sock, int proto, |
| 91 | union sockaddr_union* to, unsigned int id, |
| 92 | char* buf, int len, struct sip_msg* msg) |
| 93 | { |
| 94 | str out_buff; |
| 95 | unsigned short port; |
| 96 | char *ip; |
| 97 | |
| 98 | if (proto<=PROTO_NONE || proto>=PROTO_OTHER) { |
| 99 | LM_BUG("bogus proto %s/%d received!\n",proto2a(proto),proto); |
| 100 | return -1; |
| 101 | } |
| 102 | if (protos[proto].id==PROTO_NONE) { |
| 103 | LM_ERR("trying to using proto %s/%d which is not initialized!\n", |
| 104 | proto2a(proto),proto); |
| 105 | return -1; |
| 106 | } |
| 107 | |
| 108 | out_buff.len = len; |
| 109 | out_buff.s = buf; |
| 110 | |
| 111 | /* determine the send socket */ |
| 112 | if (send_sock==0) |
| 113 | send_sock=get_send_socket(0, to, proto); |
| 114 | if (send_sock==0){ |
| 115 | LM_ERR("no sending socket found for proto %s/%d\n", |
| 116 | proto2a(proto), proto); |
| 117 | goto error; |
| 118 | } |
| 119 | |
| 120 | /* the raw processing callbacks are free to change whatever inside |
| 121 | * the buffer further use out_buff.s and at the end try to free out_buff.s |
| 122 | * if changed by callbacks */ |
| 123 | if ( is_sip_proto(proto) ) |
| 124 | run_post_raw_processing_cb(POST_RAW_PROCESSING,&out_buff, msg); |
| 125 | |
| 126 | /* update the length for further processing */ |
| 127 | len = out_buff.len; |
| 128 | if ((send_sock->flags & SI_INTERNAL) && send_sock->internal_proto != PROTO_NONE) |
| 129 | proto = send_sock->internal_proto; |
| 130 | |
| 131 | if (protos[proto].tran.send(send_sock, out_buff.s, out_buff.len, to, id, |
| 132 | msg) < 0){ |
| 133 | get_su_info(to, ip, port); |
| 134 | LM_ERR("send() to %s:%hu for proto %s/%d failed\n", |
| 135 | ip, port, proto2a(proto),proto); |
| 136 | goto error; |
| 137 | } |
| 138 | |
| 139 | /* potentially allocated by the out raw processing */ |
| 140 | if (out_buff.s != buf) |
| 141 | pkg_free(out_buff.s); |
| 142 | |
| 143 | return 0; |
| 144 | error: |
| 145 | if (out_buff.s != buf) |
| 146 | pkg_free(out_buff.s); |
| 147 | return -1; |
no test coverage detected