}
client_p->localClient->F = xF[0];
+ client_p->localClient->ssl_callback = serv_connect_callback;
+ client_p->localClient->ssl_data = data;
client_p->localClient->ssl_ctl = start_ssld_connect(F, xF[1], connid_get(client_p));
if(!client_p->localClient->ssl_ctl)
return;
}
SetSSL(client_p);
- serv_connect_callback(client_p->localClient->F, RB_OK, client_p);
}
/*
/* COMM_ERR_TIMEOUT wont have an errno associated with it,
* the others will.. --fl
*/
- if(status == RB_ERR_TIMEOUT)
+ if(status == RB_ERR_TIMEOUT || status == RB_ERROR_SSL)
{
sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) ? L_NETWIDE : L_ALL,
"Error connecting to %s[%s]: %s",
zips->out_ratio = 0;
}
+static void
+ssl_process_open_fd(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
+{
+ struct Client *client_p;
+ uint32_t fd;
+
+ if(ctl_buf->buflen < 5)
+ return; /* bogus message..drop it.. XXX should warn here */
+
+ fd = buf_to_uint32(&ctl_buf->buf[1]);
+ client_p = find_cli_connid_hash(fd);
+ if(client_p == NULL || client_p->localClient == NULL)
+ return;
+
+ if(client_p->localClient->ssl_callback)
+ {
+ CNCB *hdl = client_p->localClient->ssl_callback;
+ void *data = client_p->localClient->ssl_data;
+
+ client_p->localClient->ssl_callback = NULL;
+ client_p->localClient->ssl_data = NULL;
+
+ hdl(client_p->localClient->F, RB_OK, data);
+ }
+}
+
static void
ssl_process_dead_fd(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
{
fd = buf_to_uint32(&ctl_buf->buf[1]);
rb_strlcpy(reason, &ctl_buf->buf[5], sizeof(reason));
client_p = find_cli_connid_hash(fd);
- if(client_p == NULL)
+ if(client_p == NULL || client_p->localClient == NULL)
return;
+
+ if(IsAnyServer(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) && !IsServer(client_p) ? L_NETWIDE : L_ALL, "ssld error for %s: %s", client_p->name, reason);
+ ilog(L_SERVER, "ssld error for %s: %s", log_client_name(client_p, SHOW_IP), reason);
+ }
+
+ /* if there is still a pending callback, call it now */
+ if(client_p->localClient->ssl_callback)
+ {
+ CNCB *hdl = client_p->localClient->ssl_callback;
+ void *data = client_p->localClient->ssl_data;
+
+ client_p->localClient->ssl_callback = NULL;
+ client_p->localClient->ssl_data = NULL;
+
+ hdl(client_p->localClient->F, RB_ERROR_SSL, data);
+
+ /* the callback should have exited the client */
+ return;
+ }
+
if(IsAnyServer(client_p) || IsRegistered(client_p))
{
/* read any last moment ERROR, QUIT or the like -- jilles */
if (IsAnyDead(client_p))
return;
}
- if(IsAnyServer(client_p))
- {
- sendto_realops_snomask(SNO_GENERAL, is_remote_connect(client_p) && !IsServer(client_p) ? L_NETWIDE : L_ALL, "ssld error for %s: %s", client_p->name, reason);
- ilog(L_SERVER, "ssld error for %s: %s", log_client_name(client_p, SHOW_IP), reason);
- }
exit_client(client_p, client_p, &me, reason);
}
case 'N':
ircd_ssl_ok = false; /* ssld says it can't do ssl/tls */
break;
+ case 'O':
+ ssl_process_open_fd(ctl, ctl_buf);
+ break;
case 'D':
ssl_process_dead_fd(ctl, ctl_buf);
break;
mod_cmd_write_queue(conn->ctl, buf, 9 + len);
}
+static void
+ssl_send_open(conn_t *conn)
+{
+ uint8_t buf[5];
+
+ buf[0] = 'O';
+ uint32_to_buf(&buf[1], conn->id);
+ mod_cmd_write_queue(conn->ctl, buf, 5);
+}
+
static void
ssl_process_accept_cb(rb_fde_t *F, int status, struct sockaddr *addr, rb_socklen_t len, void *data)
{
{
ssl_send_cipher(conn);
ssl_send_certfp(conn);
+ ssl_send_open(conn);
conn_mod_read_cb(conn->mod_fd, conn);
conn_plain_read_cb(conn->plain_fd, conn);
return;
{
ssl_send_cipher(conn);
ssl_send_certfp(conn);
+ ssl_send_open(conn);
conn_mod_read_cb(conn->mod_fd, conn);
conn_plain_read_cb(conn->plain_fd, conn);
}