void net_send_queue(struct connection *c, void *data, u_int32_t len, struct spdy_stream *s, int before) { u_int8_t *d; struct netbuf *nb; u_int32_t avail; kore_debug("net_send_queue(%p, %p, %d, %p, %d)", c, data, len, s, before); d = data; if (before == NETBUF_LAST_CHAIN) { nb = TAILQ_LAST(&(c->send_queue), netbuf_head); if (nb != NULL && !(nb->flags & NETBUF_IS_STREAM) && nb->stream == s && nb->b_len < nb->m_len) { avail = nb->m_len - nb->b_len; if (len < avail) { memcpy(nb->buf + nb->b_len, d, len); nb->b_len += len; return; } else if (len > avail) { memcpy(nb->buf + nb->b_len, d, avail); nb->b_len += avail; len -= avail; d += avail; if (len == 0) return; } } } nb = kore_pool_get(&nb_pool); nb->flags = 0; nb->cb = NULL; nb->owner = c; nb->s_off = 0; nb->stream = s; nb->b_len = len; nb->type = NETBUF_SEND; if (nb->b_len < NETBUF_SEND_PAYLOAD_MAX) nb->m_len = NETBUF_SEND_PAYLOAD_MAX; else nb->m_len = nb->b_len; nb->buf = kore_malloc(nb->m_len); if (len > 0) memcpy(nb->buf, d, nb->b_len); if (before == NETBUF_BEFORE_CHAIN) { TAILQ_INSERT_BEFORE(c->snb, nb, list); } else { TAILQ_INSERT_TAIL(&(c->send_queue), nb, list); } }
int kore_connection_accept(struct listener *l, struct connection **out) { socklen_t len; struct connection *c; kore_debug("kore_connection_accept(%p)", l); *out = NULL; len = sizeof(struct sockaddr_in); c = kore_pool_get(&connection_pool); if ((c->fd = accept(l->fd, (struct sockaddr *)&(c->sin), &len)) == -1) { kore_pool_put(&connection_pool, c); kore_debug("accept(): %s", errno_s); return (KORE_RESULT_ERROR); } if (!kore_connection_nonblock(c->fd)) { close(c->fd); kore_pool_put(&connection_pool, c); return (KORE_RESULT_ERROR); } c->owner = l; c->ssl = NULL; c->flags = 0; c->inflate_started = 0; c->deflate_started = 0; c->client_stream_id = 0; c->proto = CONN_PROTO_UNKNOWN; c->state = CONN_STATE_SSL_SHAKE; c->wsize_initial = SPDY_INIT_WSIZE; c->idle_timer.start = 0; c->idle_timer.length = KORE_IDLE_TIMER_MAX; TAILQ_INIT(&(c->send_queue)); TAILQ_INIT(&(c->recv_queue)); TAILQ_INIT(&(c->spdy_streams)); kore_worker_connection_add(c); kore_connection_start_idletimer(c); *out = c; return (KORE_RESULT_OK); }
void net_recv_queue(struct connection *c, u_int32_t len, int flags, int (*cb)(struct netbuf *)) { kore_debug("net_recv_queue(): %p %d %d", c, len, flags); if (c->rnb != NULL) fatal("net_recv_queue(): called incorrectly for %p", c); c->rnb = kore_pool_get(&nb_pool); c->rnb->cb = cb; c->rnb->owner = c; c->rnb->s_off = 0; c->rnb->b_len = len; c->rnb->m_len = len; c->rnb->extra = NULL; c->rnb->flags = flags; c->rnb->type = NETBUF_RECV; c->rnb->buf = kore_malloc(c->rnb->b_len); }
void net_send_stream(struct connection *c, void *data, u_int32_t len, int (*cb)(struct netbuf *), struct netbuf **out) { struct netbuf *nb; kore_debug("net_send_stream(%p, %p, %d)", c, data, len); nb = kore_pool_get(&nb_pool); nb->cb = cb; nb->owner = c; nb->s_off = 0; nb->buf = data; nb->b_len = len; nb->m_len = nb->b_len; nb->type = NETBUF_SEND; nb->flags = NETBUF_IS_STREAM; TAILQ_INSERT_TAIL(&(c->send_queue), nb, list); if (out != NULL) *out = nb; }