static int req_connect(struct http_req *req) { int err = EINVAL; while (req->srvc > 0) { --req->srvc; tmr_cancel(&req->tmr); req->sc = mem_deref(req->sc); req->tc = mem_deref(req->tc); req->mb = mem_deref(req->mb); err = tcp_connect(&req->tc, &req->srvv[req->srvc], estab_handler, recv_handler, close_handler, req); if (err) continue; #ifdef USE_TLS if (req->secure) { err = tls_start_tcp(&req->sc, req->tls, req->tc, 0); if (err) { req->tc = mem_deref(req->tc); continue; } } #endif tmr_start(&req->tmr, CONN_TIMEOUT, timeout_handler, req); break; } return err; }
static void tcp_connect_handler(const struct sa *paddr, void *arg) { struct sip_transport *transp = arg; struct sip_conn *conn; int err; conn = mem_zalloc(sizeof(*conn), conn_destructor); if (!conn) { err = ENOMEM; goto out; } hash_append(transp->sip->ht_conn, sa_hash(paddr, SA_ALL), &conn->he, conn); conn->paddr = *paddr; conn->sip = transp->sip; err = tcp_accept(&conn->tc, transp->sock, tcp_estab_handler, tcp_recv_handler, tcp_close_handler, conn); if (err) goto out; err = tcp_conn_local_get(conn->tc, &conn->laddr); if (err) goto out; #ifdef USE_TLS if (transp->tls) { err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0); if (err) goto out; } #endif tmr_start(&conn->tmr, TCP_ACCEPT_TIMEOUT * 1000, conn_tmr_handler, conn); out: if (err) { tcp_reject(transp->sock); mem_deref(conn); } }
void http_send(struct request *request) { int ok; if(request->state == START) { ok = sa_decode(&request->dest, request->host, strlen(request->host)); if(ok == 0) { request->state = RESOLVED; } else { http_resolve(request); return; } } tcp_connect(&request->tcp, &request->dest, tcp_estab_handler, tcp_recv_handler, tcp_close_handler, request); if(request->secure) { ok = tls_start_tcp(&request->ssl, request->app->tls, request->tcp, 0); DEBUG_INFO("start ssl %d\n", ok); } }
static int start(struct allocation *alloc) { struct sa laddr; int err = 0; if (!alloc) return EINVAL; sa_init(&laddr, sa_af(&alloc->srv)); switch (alloc->proto) { case IPPROTO_UDP: err = udp_listen(&alloc->us, &laddr, udp_recv, alloc); if (err) { re_fprintf(stderr, "allocation: failed to" " create UDP socket" " (%m)\n", err); goto out; } udp_sockbuf_set(alloc->us, 524288); if (alloc->secure) { /* note: re-using UDP socket for DTLS-traffic */ err = dtls_listen(&alloc->dtls_sock, NULL, alloc->us, 2, DTLS_LAYER, NULL, NULL); if (err) { re_fprintf(stderr, "dtls_listen error: %m\n", err); goto out; } err = dtls_connect(&alloc->tlsc, alloc->tls, alloc->dtls_sock, &alloc->srv, dtls_estab_handler, dtls_recv_handler, dtls_close_handler, alloc); if (err) { re_fprintf(stderr, "dtls_connect error: %m\n", err); goto out; } } else { err = turnc_alloc(&alloc->turnc, NULL, IPPROTO_UDP, alloc->us, TURN_LAYER, &alloc->srv, alloc->user, alloc->pass, TURN_DEFAULT_LIFETIME, turnc_handler, alloc); if (err) { re_fprintf(stderr, "allocation: failed to" " create TURN client" " (%m)\n", err); goto out; } } break; case IPPROTO_TCP: err = tcp_connect(&alloc->tc, &alloc->srv, tcp_estab_handler, tcp_recv_handler, tcp_close_handler, alloc); if (err) break; if (alloc->secure) { err = tls_start_tcp(&alloc->tlsc, alloc->tls, alloc->tc, 0); if (err) break; } break; default: err = EPROTONOSUPPORT; goto out; } out: return err; }
static int conn_send(struct sip_connqent **qentp, struct sip *sip, bool secure, const struct sa *dst, struct mbuf *mb, sip_transp_h *transph, void *arg) { struct sip_conn *conn, *new_conn = NULL; struct sip_connqent *qent; int err = 0; conn = conn_find(sip, dst, secure); if (conn) { if (!conn->established) goto enqueue; return tcp_send(conn->tc, mb); } new_conn = conn = mem_zalloc(sizeof(*conn), conn_destructor); if (!conn) return ENOMEM; hash_append(sip->ht_conn, sa_hash(dst, SA_ALL), &conn->he, conn); conn->paddr = *dst; conn->sip = sip; err = tcp_connect(&conn->tc, dst, tcp_estab_handler, tcp_recv_handler, tcp_close_handler, conn); if (err) goto out; err = tcp_conn_local_get(conn->tc, &conn->laddr); if (err) goto out; #ifdef USE_TLS if (secure) { const struct sip_transport *transp; transp = transp_find(sip, SIP_TRANSP_TLS, sa_af(dst), dst); if (!transp || !transp->tls) { err = EPROTONOSUPPORT; goto out; } err = tls_start_tcp(&conn->sc, transp->tls, conn->tc, 0); if (err) goto out; } #endif tmr_start(&conn->tmr, TCP_IDLE_TIMEOUT * 1000, conn_tmr_handler, conn); enqueue: qent = mem_zalloc(sizeof(*qent), qent_destructor); if (!qent) { err = ENOMEM; goto out; } list_append(&conn->ql, &qent->le, qent); qent->mb = mem_ref(mb); qent->transph = transph ? transph : internal_transport_handler; qent->arg = arg; if (qentp) { qent->qentp = qentp; *qentp = qent; } out: if (err) mem_deref(new_conn); return err; }