lcbio_SOCKET * lcbio_wrap_fd(lcbio_pTABLE iot, lcb_settings *settings, lcb_socket_t fd) { lcbio_SOCKET *ret = calloc(1, sizeof(*ret)); lcbio_CONNDONE_cb *ci = calloc(1, sizeof(*ci)); if (ret == NULL || ci == NULL) { free(ret); free(ci); return NULL; } assert(iot->model = LCB_IOMODEL_EVENT); lcb_list_init(&ret->protos); ret->settings = settings; ret->io = iot; ret->refcount = 1; ret->u.fd = fd; lcbio_table_ref(ret->io); lcb_settings_ref(ret->settings); lcbio__load_socknames(ret); return ret; }
LCB_INTERNAL_API lcb_timer_t lcb_timer_create2(lcbio_TABLE *io, const void *cookie, lcb_uint32_t usec, lcb_timer_options options, lcb_timer_callback callback, lcb_t instance, lcb_error_t *error) { lcb_timer_t tmr = calloc(1, sizeof(struct lcb_timer_st)); tmr->io = io; if (!tmr) { *error = LCB_CLIENT_ENOMEM; return NULL; } if (!callback) { *error = LCB_EINVAL; return NULL; } if (! (options & LCB_TIMER_STANDALONE)) { lcb_assert(instance); } lcbio_table_ref(tmr->io); tmr->instance = instance; tmr->callback = callback; tmr->cookie = cookie; tmr->options = options; tmr->event = io->timer.create(io->p); if (tmr->event == NULL) { free(tmr); *error = LCB_CLIENT_ENOMEM; return NULL; } if ( (options & LCB_TIMER_STANDALONE) == 0) { lcb_aspend_add(&instance->pendops, LCB_PENDTYPE_TIMER, tmr); } lcb_timer_rearm(tmr, usec); *error = LCB_SUCCESS; return tmr; }
/****************************************************************************** ****************************************************************************** ** Common Routines for lcbio_TABLE Emulation ** ****************************************************************************** ******************************************************************************/ void iotssl_init_common(lcbio_XSSL *xs, lcbio_TABLE *orig, SSL_CTX *sctx) { lcbio_TABLE *base = &xs->base_; xs->iops_dummy_ = calloc(1, sizeof(*xs->iops_dummy_)); xs->iops_dummy_->v.v0.cookie = xs; xs->orig = orig; base->model = xs->orig->model; base->p = xs->iops_dummy_; base->refcount = 1; base->loop.start = loop_run; base->loop.stop = loop_stop; base->timer.create = create_timer; base->timer.destroy = destroy_timer; base->timer.schedule = schedule_timer; base->timer.cancel = cancel_timer; if (orig->model == LCB_IOMODEL_EVENT) { base->u_io.v0.ev.create = create_event; base->u_io.v0.ev.destroy = destroy_event; base->u_io.v0.io.is_closed = Eis_closed; } else { base->u_io.completion.is_closed = Cis_closed; } lcbio_table_ref(xs->orig); xs->error = 0; xs->ssl = SSL_new(sctx); xs->rbio = BIO_new(BIO_s_mem()); xs->wbio = BIO_new(BIO_s_mem()); SSL_set_bio(xs->ssl, xs->rbio, xs->wbio); SSL_set_read_ahead(xs->ssl, 0); /* Indicate that we are a client */ SSL_set_connect_state(xs->ssl); }
struct lcbio_CONNSTART * lcbio_connect(lcbio_TABLE *iot, lcb_settings *settings, lcb_host_t *dest, uint32_t timeout, lcbio_CONNDONE_cb handler, void *arg) { lcbio_SOCKET *s; lcbio_CONNSTART *ret; struct addrinfo hints; int rv; s = calloc(1, sizeof(*s)); ret = calloc(1, sizeof(*ret)); /** Initialize the socket first */ s->io = iot; s->settings = settings; s->ctx = ret; s->refcount = 1; s->info = calloc(1, sizeof(*s->info)); s->info->ep = *dest; lcbio_table_ref(s->io); lcb_settings_ref(s->settings); lcb_list_init(&s->protos); if (IOT_IS_EVENT(iot)) { s->u.fd = INVALID_SOCKET; ret->event = IOT_V0EV(iot).create(IOT_ARG(iot)); } /** Initialize the connstart structure */ ret->handler = handler; ret->arg = arg; ret->sock = s; ret->async = lcbio_timer_new(iot, ret, cs_handler); lcbio_timer_rearm(ret->async, timeout); lcb_log(LOGARGS(s, INFO), CSLOGFMT "Starting. Timeout=%uus", CSLOGID(s), timeout); /** Hostname lookup: */ memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; if (settings->ipv6 == LCB_IPV6_DISABLED) { hints.ai_family = AF_INET; } else if (settings->ipv6 == LCB_IPV6_ONLY) { hints.ai_family = AF_INET6; } else { hints.ai_family = AF_UNSPEC; } if ((rv = getaddrinfo(dest->host, dest->port, &hints, &ret->ai_root))) { const char *errstr = rv != EAI_SYSTEM ? gai_strerror(rv) : ""; lcb_log(LOGARGS(s, ERR), CSLOGFMT "Couldn't look up %s (%s) [EAI=%d]", CSLOGID(s), dest->host, errstr, rv); cs_state_signal(ret, CS_ERROR, LCB_UNKNOWN_HOST); } else { ret->ai = ret->ai_root; /** Figure out how to connect */ if (IOT_IS_EVENT(iot)) { E_connect(-1, LCB_WRITE_EVENT, ret); } else { C_connect(ret); } } return ret; }