static ad_conn_t *conn_new(ad_server_t *server, struct bufferevent *buffer) { if (server == NULL || buffer == NULL) { return NULL; } // Create a new connection container. ad_conn_t *conn = NEW_OBJECT(ad_conn_t); if (conn == NULL) return NULL; // Initialize with default values. conn->server = server; conn->buffer = buffer; conn->in = bufferevent_get_input(buffer); conn->out = bufferevent_get_output(buffer); conn_reset(conn); // Bind callback bufferevent_setcb(buffer, conn_read_cb, conn_write_cb, conn_event_cb, (void *)conn); bufferevent_setwatermark(buffer, EV_WRITE, 0, 0); bufferevent_enable(buffer, EV_WRITE); bufferevent_enable(buffer, EV_READ); // Run callbacks with AD_EVENT_INIT event. conn->status = call_hooks(AD_EVENT_INIT | AD_EVENT_WRITE, conn); return conn; }
/* Run a transition of the FSM */ int fsm_step(url_t* url, pfd_t* pfd) { int rc1 = 0, rc2 = 0; char buffer[BUFSIZ]; /* To pass in to readConn */ conn_t* conn = conn_get(pfd_getfd(pfd)); if (pfd->revents & POLLOUT) rc1 = writeConn(url, conn); if (pfd->revents & POLLIN) rc2 = readConn(conn, buffer, sizeof(buffer)); if (verbose > 2) fprintf(stderr, "Stepped conn #%d -> %s\n", conn->index, state_names[conn->state]); if (rc2 == ST_OK && out_file != 0) fprintf(out_file, "%s %s\n", conn->last_etag, conn->last_path); if (rc2 == ST_OK || rc2 == ST_DUP) { conn_reset(conn, (struct sockaddr*) &url->addr); } if (rc1 == ST_ERROR || rc2 == ST_ERROR) { if (verbose) { char buf[100]; snprintf(buf, sizeof(buf), "FSM error {r:%s w:%s}", rc_names[rc2], rc_names[rc1]); error(conn, buf); } conn_reset(conn, (struct sockaddr*) &url->addr); } if (rc1 != ST_OK && rc1 != ST_CONTINUE) return rc1; return rc2; }
static void conn_free(ad_conn_t *conn) { if (conn) { if (conn->status != AD_CLOSE) { call_hooks(AD_EVENT_CLOSE | AD_EVENT_SHUTDOWN , conn); } conn_reset(conn); if (conn->buffer) { if (conn->server->sslctx) { int sslerr = bufferevent_get_openssl_error(conn->buffer); if (sslerr) { char errmsg[256]; ERR_error_string_n(sslerr, errmsg, sizeof(errmsg)); ERROR("SSL %s (err:%d)", errmsg, sslerr); } } bufferevent_free(conn->buffer); } free(conn); } }