static int proto_tls_send(struct socket_info* send_sock, char* buf, unsigned int len, union sockaddr_union* to, int id) { struct tcp_connection *c; struct ip_addr ip; int port; int fd, n; struct tls_data* data; if (to){ su2ip_addr(&ip, to); port=su_getport(to); n = tcp_conn_get(id, &ip, port, PROTO_TLS, &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"); return -1; } if (n<0) { /* error during conn get, return with error too */ LM_ERR("failed to acquire connection\n"); 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=tls_sync_connect(send_sock, to, &fd))==0) { LM_ERR("connect failed\n"); return -1; } goto send_it; } /* 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: /* if there is pending tracing data on a connection startet by us * (connected) -> flush it * As this is a write op, we look only for connected conns, not to conflict * with accepted conns (flushed on read op) */ if ( (c->flags&F_CONN_ACCEPTED)==0 && c->proto_flags & F_TLS_TRACE_READY ) { data = c->proto_data; /* send the message if set from tls_mgm */ if ( data->message ) { send_trace_message( data->message, t_dst); data->message = NULL; } /* don't allow future traces for this connection */ data->tprot = 0; data->dest = 0; c->proto_flags &= ~( F_TLS_TRACE_READY ); } LM_DBG("sending via fd %d...\n",fd); lock_get(&c->write_lock); n = tls_blocking_write(c, fd, buf, len, &tls_mgm_api); lock_release(&c->write_lock); tcp_conn_set_lifetime( c, tcp_con_lifetime); LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd); LM_DBG("buf=\n%.*s\n", (int)len, buf); 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; }
static int proto_tls_send(struct socket_info* send_sock, char* buf, unsigned int len, union sockaddr_union* to, int id) { struct tcp_connection *c; struct ip_addr ip; int port; int fd, n; 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"); return -1; } if (n<0) { /* error during conn get, return with error too */ LM_ERR("failed to aquire connection\n"); 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=tls_sync_connect(send_sock, to, &fd))==0) { LM_ERR("connect failed\n"); return -1; } goto send_it; } /* 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 = tls_blocking_write(c, fd, buf, len); tcp_conn_set_lifetime( c, tcp_con_lifetime); LM_DBG("after write: c= %p n=%d fd=%d\n",c, n, fd); LM_DBG("buf=\n%.*s\n", (int)len, buf); 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; }