void fd_open(int fd, int type) { assert(fd_table); struct fd_t *f = &fd_table[fd]; f->fd = fd; f->flags.open = 1; f->type = type; f->wqueue = NULL; if(fd > biggest_fd) biggest_fd = fd; sock_set_noblocking(fd); sock_set_cork(fd); }
void client_destroy(client_t *client) { if (client == NULL) return; if (client->worker) { WARN0 ("client still on worker thread"); return; } /* release the buffer now, as the buffer could be on the source queue * and may of disappeared after auth completes */ if (client->refbuf) { refbuf_release (client->refbuf); client->refbuf = NULL; } if (client->flags & CLIENT_AUTHENTICATED) DEBUG1 ("client still in auth \"%s\"", httpp_getvar (client->parser, HTTPP_VAR_URI)); /* write log entry if ip is set (some things don't set it, like outgoing * slave requests */ if (client->respcode > 0 && client->parser) logging_access(client); if (client->flags & CLIENT_IP_BAN_LIFT) { INFO1 ("lifting IP ban on client at %s", client->connection.ip); connection_release_banned_ip (client->connection.ip); client->flags &= ~CLIENT_IP_BAN_LIFT; } if (client->parser) httpp_destroy (client->parser); /* we need to free client specific format data (if any) */ if (client->free_client_data) client->free_client_data (client); free(client->username); free(client->password); client->username = NULL; client->password = NULL; client->parser = NULL; client->respcode = 0; client->free_client_data = NULL; sock_set_cork (client->connection.sock, 0); // ensure any corked data is actually sent. global_lock (); if (global.running != ICE_RUNNING || client->connection.error || (client->flags & CLIENT_KEEPALIVE) == 0 || client_connected (client) == 0) { global.clients--; config_clear_listener (client->server_conn); global_unlock (); connection_close (&client->connection); free(client); return; } global_unlock (); DEBUG0 ("keepalive detected, placing back onto worker"); sock_set_cork (client->connection.sock, 1); // reenable cork for the next go around client->counter = client->schedule_ms = timing_get_time(); client->connection.con_time = client->schedule_ms/1000; client->connection.discon.time = client->connection.con_time + 7; client->ops = &http_request_ops; client->flags = CLIENT_ACTIVE; client->shared_data = NULL; client->refbuf = NULL; client->pos = 0; client->intro_offset = client->connection.sent_bytes = 0; client_add_incoming (client); }
static struct network_client_s * _endpoint_manage_event(struct network_server_s *srv, struct endpoint_s *e) { int fd; struct sockaddr_storage ss; socklen_t ss_len; retry: memset(&ss, 0, sizeof(ss)); ss_len = sizeof(ss); fd = accept_nonblock(e->fd, (struct sockaddr*)&ss, &ss_len); if (0 > fd) { if (errno == EINTR) goto retry; if (errno != EAGAIN && errno != EWOULDBLOCK) GRID_WARN("fd=%d ACCEPT error (%d %s)", e->fd, errno, strerror(errno)); return NULL; } switch (e->flags) { case NETSERVER_THROUGHPUT: sock_set_cork(fd, TRUE); break; case NETSERVER_LATENCY: sock_set_linger_default(fd); sock_set_nodelay(fd, TRUE); sock_set_tcpquickack(fd, TRUE); break; default: break; } struct network_client_s *clt = SLICE_NEW0(struct network_client_s); if (NULL == clt) { metautils_pclose(&fd); _cnx_notify_close(srv); return NULL; } switch (_cnx_notify_accept(srv)) { case EXCESS_SOFT: clt->current_error = NEWERROR(CODE_UNAVAILABLE, "Server overloaded."); case EXCESS_NONE: break; case EXCESS_HARD: metautils_pclose(&fd); _cnx_notify_close(srv); return NULL; } clt->main_stats = srv->stats; clt->server = srv; clt->fd = fd; grid_sockaddr_to_string((struct sockaddr*)&ss, clt->peer_name, sizeof(clt->peer_name)); _client_sock_name(fd, clt->local_name, sizeof(clt->local_name)); clt->time.cnx = network_server_bogonow(srv); clt->events = CLT_READ; clt->input.first = clt->input.last = NULL; clt->output.first = clt->output.last = NULL; if (e->factory_hook) e->factory_hook(e->factory_udata, clt); return clt; }