/*! \brief Finds a tcpconn & sends on it */ static int proto_ws_send(struct socket_info* send_sock, char* buf, unsigned int len, union sockaddr_union* to, int id) { struct tcp_connection *c; struct timeval get; struct ip_addr ip; int port = 0; int fd, n; reset_tcp_vars(tcpthreshold); start_expire_timer(get,tcpthreshold); if (to){ su2ip_addr(&ip, to); port=su_getport(to); n = tcp_conn_get(id, &ip, port, &c, &fd); }else if (id){ n = tcp_conn_get(id, 0, 0, &c, &fd); }else{ LM_CRIT("prot_tls_send called with null id & to\n"); get_time_difference(get,tcpthreshold,tcp_timeout_con_get); return -1; } if (n<0) { /* error during conn get, return with error too */ LM_ERR("failed to aquire connection\n"); get_time_difference(get,tcpthreshold,tcp_timeout_con_get); return -1; } /* was connection found ?? */ if (c==0) { if (tcp_no_new_conn) { return -1; } LM_DBG("no open tcp connection found, opening new one\n"); /* create tcp connection */ if ((c=ws_connect(send_sock, to, &fd))==0) { LM_ERR("connect failed\n"); return -1; } goto send_it; } get_time_difference(get, tcpthreshold, tcp_timeout_con_get); /* now we have a connection, let's what we can do with it */ /* BE CAREFUL now as we need to release the conn before exiting !!! */ if (fd==-1) { /* connection is not writable because of its state */ /* return error, nothing to do about it */ tcp_conn_release(c, 0); return -1; } send_it: LM_DBG("sending via fd %d...\n",fd); n = ws_req_write(c, fd, buf, len); stop_expire_timer(get, tcpthreshold, "WS ops",buf,(int)len,1); tcp_conn_set_lifetime( c, tcp_con_lifetime); LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd); if (n<0){ LM_ERR("failed to send\n"); c->state=S_CONN_BAD; if (c->proc_id != process_no) close(fd); tcp_conn_release(c, 0); return -1; } /* only close the FD if not already in the context of our process either we just connected, or main sent us the FD */ if (c->proc_id != process_no) close(fd); tcp_conn_release(c, 0); return n; }
/*! \brief Finds a tcpconn & sends on it */ static int proto_wss_send(struct socket_info* send_sock, char* buf, unsigned int len, union sockaddr_union* to, int id) { struct tcp_connection *c; struct timeval get; struct ip_addr ip; int port = 0; int fd, n; struct ws_data* d; reset_tcp_vars(tcpthreshold); start_expire_timer(get,tcpthreshold); if (to){ su2ip_addr(&ip, to); port=su_getport(to); n = tcp_conn_get(id, &ip, port, PROTO_WSS, &c, &fd); }else if (id){ n = tcp_conn_get(id, 0, 0, PROTO_NONE, &c, &fd); }else{ LM_CRIT("prot_tls_send called with null id & to\n"); get_time_difference(get,tcpthreshold,tcp_timeout_con_get); return -1; } if (n<0) { /* error during conn get, return with error too */ LM_ERR("failed to acquire connection\n"); get_time_difference(get,tcpthreshold,tcp_timeout_con_get); return -1; } /* was connection found ?? */ if (c==0) { if (tcp_no_new_conn) { return -1; } if (!to) { LM_ERR("Unknown destination - cannot open new tcp connection\n"); return -1; } LM_DBG("no open tcp connection found, opening new one\n"); /* create tcp connection */ if ((c=ws_connect(send_sock, to, &fd))==0) { LM_ERR("connect failed\n"); return -1; } goto send_it; } get_time_difference(get, tcpthreshold, tcp_timeout_con_get); /* now we have a connection, let's what we can do with it */ /* BE CAREFUL now as we need to release the conn before exiting !!! */ if (fd==-1) { /* connection is not writable because of its state */ /* return error, nothing to do about it */ tcp_conn_release(c, 0); return -1; } send_it: LM_DBG("sending via fd %d...\n",fd); n = ws_req_write(c, fd, buf, len); stop_expire_timer(get, tcpthreshold, "WSS ops",buf,(int)len,1); tcp_conn_set_lifetime( c, tcp_con_lifetime); /* only here we will have all tracing data TLS + WS */ d = c->proto_data; if ( (c->flags&F_CONN_ACCEPTED)==0 && d && d->dest && d->tprot ) { if ( d->message ) { send_trace_message( d->message, t_dst); d->message = NULL; } /* don't allow future traces for this cnection */ d->tprot = 0; d->dest = 0; } LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd); if (n<0){ LM_ERR("failed to send\n"); c->state=S_CONN_BAD; if (c->proc_id != process_no) close(fd); tcp_conn_release(c, 0); return -1; } /* only close the FD if not already in the context of our process either we just connected, or main sent us the FD */ if (c->proc_id != process_no) close(fd); /* mark the ID of the used connection (tracing purposes) */ last_outgoing_tcp_id = c->id; tcp_conn_release(c, 0); return n; }