return -1;
}
-static int el_job_connecting_ssl(job_t *w)
+static int el_job_tlsing(job_t *w, int starttls)
{
int err = gnutls_handshake(w->session);
-
if (err < 0 && !gnutls_error_is_fatal(err)) {
int wr = gnutls_record_get_direction(w->session);
return el_job_setemode(w, wr ? EL_WRITING : EL_READING);
/* NB: gnutls_cipher_get_key_size() returns key length in bytes */
w->ssf = gnutls_cipher_get_key_size(gnutls_cipher_get(w->session)) * 8;
w->state = EL_LLP_READY;
+ if (starttls)
+ return el_job_setemode(w, w->mode);
return w->m->on_event(w, EL_EVT_RUNNING);
}
+static int el_job_starttlsing(job_t *w)
+{
+ return el_job_tlsing(w, true);
+}
+
+static int el_job_connecting_ssl(job_t *w)
+{
+ return el_job_tlsing(w, false);
+}
+
static int el_job_connecting(job_t *w)
{
int err = 0;
return w->m->on_event(w, EL_EVT_RUNNING);
}
-static int tls_negociate(job_t *w)
+static int tls_negotiate(job_t *w)
{
static int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 };
goto error;
w->fd = sock;
- if (ssl && tls_negociate(w) < 0)
+ if (ssl && tls_negotiate(w) < 0)
goto error;
w->llp = &el_job_connecting;
return el_job_release(w, EL_ERROR);
}
+int el_job_starttls(job_t *w)
+{
+ if (tls_negotiate(w) < 0)
+ return el_job_release(w, EL_RDHUP);
+ w->state = EL_LLP_INIT;
+ w->llp = &el_job_starttlsing;
+ return w->llp(w);
+}
+
ssize_t el_job_read(job_t *w, buffer_t *buf)
{
ssize_t nr;
__must_check__ int el_job_release(job_t *j, el_status);
__must_check__ int el_job_connect(job_t *w, struct sockaddr *, socklen_t len,
int type, int proto, int ssl);
+__must_check__ int el_job_starttls(job_t *w);
__must_check__ ssize_t el_job_read(job_t *w, buffer_t *buf);
__must_check__ ssize_t el_job_write(job_t *w, buffer_t *buf);