예제 #1
0
파일: openssl.c 프로젝트: Macs/NeoIRCd
static void
rb_ssl_accept_common(rb_fde_t *new_F)
{
	int ssl_err;
	if((ssl_err = SSL_accept((SSL *) new_F->ssl)) <= 0)
	{
		switch (ssl_err = SSL_get_error((SSL *) new_F->ssl, ssl_err))
		{
		case SSL_ERROR_SYSCALL:
			if(rb_ignore_errno(errno))
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
				{
					new_F->ssl_errno = get_last_err();
					rb_setselect(new_F, RB_SELECT_READ | RB_SELECT_WRITE,
						     rb_ssl_tryaccept, NULL);
					return;
				}
		default:
			new_F->ssl_errno = get_last_err();
			new_F->accept->callback(new_F, RB_ERROR_SSL, NULL, 0, new_F->accept->data);
			return;
		}
	}
	else
	{
		rb_ssl_tryaccept(new_F, NULL);
	}
}
예제 #2
0
파일: openssl.c 프로젝트: Macs/NeoIRCd
static void
rb_ssl_tryconn_cb(rb_fde_t *F, void *data)
{
	struct ssl_connect *sconn = data;
	int ssl_err;
	if(!SSL_is_init_finished((SSL *) F->ssl))
	{
		if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
		{
			switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
			{
			case SSL_ERROR_SYSCALL:
				if(rb_ignore_errno(errno))
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
					{
						F->ssl_errno = get_last_err();
						rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
							     rb_ssl_tryconn_cb, sconn);
						return;
					}
			default:
				F->ssl_errno = get_last_err();
				rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
				return;
			}
		}
		else
		{
			rb_ssl_connect_realcb(F, RB_OK, sconn);
		}
	}
}
예제 #3
0
파일: mbedtls.c 프로젝트: thors/ircd-ratbox
static void
rb_ssl_tryaccept(rb_fde_t *F, void *data)
{
	int ret;
	struct acceptdata *ad;

	lrb_assert(F->accept != NULL);

	ret = do_ssl_handshake(F, rb_ssl_tryaccept, NULL);

	/* do_ssl_handshake does the rb_setselect */
	if(ret == 0)
		return;

	ad = F->accept;
	F->accept = NULL;
	rb_settimeout(F, 0, NULL, NULL);
	rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);

	if(ret > 0)
		ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
	else
		ad->callback(F, RB_ERROR_SSL, NULL, 0, ad->data);

	rb_free(ad);
}
예제 #4
0
static int
rb_epoll_sched_event_timerfd(struct ev_entry *event, int when)
{
	struct itimerspec ts;
	static char buf[FD_DESC_SZ + 8];
	int fd;
	rb_fde_t *F;

	if((fd = timerfd_create(CLOCK_REALTIME, 0)) < 0)
	{
		rb_lib_log("timerfd_create: %s\n", strerror(errno));
		return 0;
	}

	memset(&ts, 0, sizeof(ts));
	ts.it_value.tv_sec = when;
	ts.it_value.tv_nsec = 0;
	if(event->frequency != 0)
		ts.it_interval = ts.it_value;

	if(timerfd_settime(fd, 0, &ts, NULL) < 0)
	{
		rb_lib_log("timerfd_settime: %s\n", strerror(errno));
		close(fd);
		return 0;
	}
	rb_snprintf(buf, sizeof(buf), "timerfd: %s", event->name);
	F = rb_open(fd, RB_FD_UNKNOWN, buf);
	rb_set_nb(F);
	event->comm_ptr = F;
	rb_setselect(F, RB_SELECT_READ, rb_read_timerfd, event);
	return 1;
}
예제 #5
0
파일: mbedtls.c 프로젝트: thors/ircd-ratbox
static int
do_ssl_handshake(rb_fde_t *F, PF * callback, void *data)
{
	int ret;
	int flags;

	ret = mbedtls_ssl_handshake(SSL_P(F));
	if(ret < 0)
	{
		if (ret == -1 && rb_ignore_errno(errno))
			ret = MBEDTLS_ERR_SSL_WANT_READ;

		if((ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE))
		{
			if(ret == MBEDTLS_ERR_SSL_WANT_READ)
				flags = RB_SELECT_READ;
			else
				flags = RB_SELECT_WRITE;
			rb_setselect(F, flags, callback, data);
			return 0;
		}

		F->sslerr.ssl_errno = ret;
		return -1;
	}
	return 1;		/* handshake is finished..go about life */
}
예제 #6
0
static void
rb_ssl_tryconn(rb_fde_t *F, int status, void *data)
{
    struct ssl_connect *sconn = data;
    int ssl_err;
    if(status != RB_OK) {
        rb_ssl_connect_realcb(F, status, sconn);
        return;
    }

    F->type |= RB_FD_SSL;
    F->ssl = SSL_new(ssl_client_ctx);
    SSL_set_fd((SSL *) F->ssl, F->fd);
    rb_setup_ssl_cb(F);
    rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
    if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0) {
        switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err)) {
        case SSL_ERROR_SYSCALL:
            if(rb_ignore_errno(errno))
            case SSL_ERROR_WANT_READ:
        case SSL_ERROR_WANT_WRITE: {
            F->ssl_errno = get_last_err();
            rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
                         rb_ssl_tryconn_cb, sconn);
            return;
        }
        default:
            F->ssl_errno = get_last_err();
            rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
            return;
        }
    } else {
        rb_ssl_connect_realcb(F, RB_OK, sconn);
    }
}
예제 #7
0
static void
rb_read_timerfd(rb_fde_t *F, void *data)
{
	struct ev_entry *event = (struct ev_entry *)data;
	int retlen;
	uint64_t count;

	if(event == NULL)
	{
		rb_close(F);
		return;
	}

	retlen = rb_read(F, &count, sizeof(count));

	if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
	{
		rb_close(F);
		rb_lib_log("rb_read_timerfd: timerfd[%s] closed on error: %s", event->name,
			   strerror(errno));
		return;
	}
	rb_setselect(F, RB_SELECT_READ, rb_read_timerfd, event);
	rb_run_event(event);
}
예제 #8
0
파일: openssl.c 프로젝트: Macs/NeoIRCd
static void
rb_ssl_tryaccept(rb_fde_t *F, void *data)
{
	int ssl_err;
	lrb_assert(F->accept != NULL);
	int flags;
	struct acceptdata *ad;

	if(!SSL_is_init_finished((SSL *) F->ssl))
	{
		if((ssl_err = SSL_accept((SSL *) F->ssl)) <= 0)
		{
			switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
			{
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
				if(ssl_err == SSL_ERROR_WANT_WRITE)
					flags = RB_SELECT_WRITE;
				else
					flags = RB_SELECT_READ;
				F->ssl_errno = get_last_err();
				rb_setselect(F, flags, rb_ssl_tryaccept, NULL);
				break;
			case SSL_ERROR_SYSCALL:
				F->accept->callback(F, RB_ERROR, NULL, 0, F->accept->data);
				break;
			default:
				F->ssl_errno = get_last_err();
				F->accept->callback(F, RB_ERROR_SSL, NULL, 0, F->accept->data);
				break;
			}
			return;
		}
	}
	rb_settimeout(F, 0, NULL, NULL);
	rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE, NULL, NULL);

	ad = F->accept;
	F->accept = NULL;
	ad->callback(F, RB_OK, (struct sockaddr *)&ad->S, ad->addrlen, ad->data);
	rb_free(ad);

}
예제 #9
0
파일: openssl.c 프로젝트: thors/ircd-ratbox
void
rb_ssl_start_connected(rb_fde_t *F, CNCB * callback, void *data, int timeout)
{
	ssl_connect_t *sconn;
	int ssl_err;
	if(F == NULL)
		return;

	sconn = rb_malloc(sizeof(ssl_connect_t));
	sconn->data = data;
	sconn->callback = callback;
	sconn->timeout = timeout;
	F->connect = rb_malloc(sizeof(struct conndata));
	F->connect->callback = callback;
	F->connect->data = data;
	F->type |= RB_FD_SSL;
	F->ssl = SSL_new(F->sctx->ssl_ctx);

        if(F->ssl == NULL)
        {
                F->sslerr.ssl_errno = get_last_err();
                rb_lib_log("rb_ssl_start_Connected: SSL_new() fails: %s", ERR_error_string(F->sslerr.ssl_errno, NULL));
                
                rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
                return;
        }

	SSL_set_fd((SSL *) F->ssl, F->fd);
	rb_setup_ssl_cb(F);
	rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn);
	if((ssl_err = SSL_connect((SSL *) F->ssl)) <= 0)
	{
		switch (ssl_err = SSL_get_error((SSL *) F->ssl, ssl_err))
		{
		case SSL_ERROR_SYSCALL:
			if(rb_ignore_errno(errno))
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
				{
					F->sslerr.ssl_errno = get_last_err();
					rb_setselect(F, RB_SELECT_READ | RB_SELECT_WRITE,
						     rb_ssl_tryconn_cb, sconn);
					return;
				}
		default:
			F->sslerr.ssl_errno = get_last_err();
			rb_ssl_connect_realcb(F, RB_ERROR_SSL, sconn);
			return;
		}
	}
	else
	{
		rb_ssl_connect_realcb(F, RB_OK, sconn);
	}
}
예제 #10
0
static void
signalfd_handler(rb_fde_t *F, void *data)
{
	static struct our_signalfd_siginfo fdsig[SIGFDIOV_COUNT];
	static struct iovec iov[SIGFDIOV_COUNT];
	struct ev_entry *ev;
	int ret, x;

	for(x = 0; x < SIGFDIOV_COUNT; x++)
	{
		iov[x].iov_base = &fdsig[x];
		iov[x].iov_len = sizeof(struct our_signalfd_siginfo);
	}

	while(1)
	{
		ret = readv(rb_get_fd(F), iov, SIGFDIOV_COUNT);

		if(ret == 0 || (ret < 0 && !rb_ignore_errno(errno)))
		{
			rb_close(F);
			rb_epoll_init_event();
			return;
		}

		if(ret < 0)
		{
			rb_setselect(F, RB_SELECT_READ, signalfd_handler, NULL);
			return;
		}
		for(x = 0; x < ret / (int)sizeof(struct our_signalfd_siginfo); x++)
		{
#if __WORDSIZE == 32 && defined(__sparc__)
			uint32_t *q = (uint32_t *)&fdsig[x].svptr;
			ev = (struct ev_entry *)q[0];
#else
			ev = (struct ev_entry *)(uintptr_t)(fdsig[x].svptr);

#endif
			if(ev == NULL)
				continue;
			rb_run_event(ev);
		}
	}
}
예제 #11
0
파일: helper.c 프로젝트: awilfox/charybdis
static void
rb_helper_write_sendq(rb_fde_t *F, void *helper_ptr)
{
	rb_helper *helper = helper_ptr;
	int retlen;

	if(rb_linebuf_len(&helper->sendq) > 0)
	{
		while((retlen = rb_linebuf_flush(F, &helper->sendq)) > 0)
			;
		if(retlen == 0 || (retlen < 0 && !rb_ignore_errno(errno)))
		{
			rb_helper_restart(helper);
			return;
		}
	}

	if(rb_linebuf_len(&helper->sendq) > 0)
		rb_setselect(helper->ofd, RB_SELECT_WRITE, rb_helper_write_sendq, helper);
}
예제 #12
0
static void
rb_helper_read_cb(rb_fde_t *F, void *data)
{
    rb_helper *helper = (rb_helper *)data;
    char buf[4096];
    ssize_t length;
    if(helper == NULL)
        return;

    while((length = rb_read(helper->ifd, buf, sizeof(buf))) > 0)
    {
        rb_linebuf_parse(helper->recvq, buf, (size_t)length, 0);
        helper->read_cb(helper);
    }
    if(length == 0 || (length < 0 && !rb_ignore_errno(errno)))
    {
        rb_helper_restart(helper);
        return;
    }

    rb_setselect(helper->ifd, RB_SELECT_READ, rb_helper_read_cb, helper);
}
예제 #13
0
파일: gnutls.c 프로젝트: azzurra/bluebox
static int
do_ssl_handshake(rb_fde_t *F, PF * callback)
{
    int ret;
    int flags;

    ret = gnutls_handshake(SSL_P(F));
    if (ret < 0)
    {
        if ((ret == GNUTLS_E_INTERRUPTED && rb_ignore_errno(errno)) || ret == GNUTLS_E_AGAIN)
        {
            if (gnutls_record_get_direction(SSL_P(F)) == 0)
                flags = RB_SELECT_READ;
            else
                flags = RB_SELECT_WRITE;
            rb_setselect(F, flags, callback, NULL);
            return 0;
        }
        F->ssl_errno = ret;
        return -1;
    }
    return 1;       /* handshake is finished..go about life */
}