void process_sub_read_buf(sub_client *c) { while (sdslen(c->read_buf)) { if (c->read_buf[0] == '*') { c->req_type = REQ_MULTIBULK; } else { c->req_type = REQ_INLINE; } if (c->req_type == REQ_INLINE) { if (process_inline_buffer(c) != SUBCLI_OK) break; } else if (c->req_type == REQ_MULTIBULK) { if (process_multibulk_buffer(c) != SUBCLI_OK) break; } else { srv_log(LOG_ERROR, "error req_type %d", c->req_type); exit(EXIT_FAILURE); } } if (c->argc == 0) { free_client_argv(c); } else { if (process_command(c) == SUBCLI_OK) { reset_client(c); } } }
static int new_client_callback(int cid, void *user) { clients[cid].state = SRVCLIENT_STATE_AUTH; clients[cid].name[0] = 0; clients[cid].clan[0] = 0; clients[cid].authed = 0; reset_client(cid); return 0; }
static void client_done(client *c) { if (conf.requests_finished == conf.requests) { free_client(c); quit = 1; return; } if (conf.keep_alive) { reset_client(c); } else { --conf.live_clients; create_missing_clients(c); ++conf.live_clients; free_client(c); } }
static void isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) { isc_httpd_t *httpd = ev->ev_arg; isc_region_t r; isc_socketevent_t *sev = (isc_socketevent_t *)ev; ENTER("senddone"); INSIST(ISC_HTTPD_ISSEND(httpd)); /* * First, unlink our header buffer from the socket's bufflist. This * is sort of an evil hack, since we know our buffer will be there, * and we know it's address, so we can just remove it directly. */ NOTICE("senddone unlinked header"); ISC_LIST_UNLINK(sev->bufferlist, &httpd->headerbuffer, link); /* * We will always want to clean up our receive buffer, even if we * got an error on send or we are shutting down. * * We will pass in the buffer only if there is data in it. If * there is no data, we will pass in a NULL. */ if (httpd->freecb != NULL) { isc_buffer_t *b = NULL; if (isc_buffer_length(&httpd->bodybuffer) > 0) b = &httpd->bodybuffer; httpd->freecb(b, httpd->freecb_arg); NOTICE("senddone free callback performed"); } if (ISC_LINK_LINKED(&httpd->bodybuffer, link)) { ISC_LIST_UNLINK(sev->bufferlist, &httpd->bodybuffer, link); NOTICE("senddone body buffer unlinked"); } if (sev->result != ISC_R_SUCCESS) { destroy_client(&httpd); goto out; } if ((httpd->flags & HTTPD_CLOSE) != 0) { destroy_client(&httpd); goto out; } ISC_HTTPD_SETRECV(httpd); NOTICE("senddone restarting recv on socket"); reset_client(httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; /* check return code? */ (void)isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); out: isc_event_free(&ev); EXIT("senddone"); }
static void isc_httpd_accept(isc_task_t *task, isc_event_t *ev) { isc_result_t result; isc_httpdmgr_t *httpdmgr = ev->ev_arg; isc_httpd_t *httpd; isc_region_t r; isc_socket_newconnev_t *nev = (isc_socket_newconnev_t *)ev; isc_sockaddr_t peeraddr; ENTER("accept"); LOCK(&httpdmgr->lock); if (MSHUTTINGDOWN(httpdmgr)) { NOTICE("accept shutting down, goto out"); goto out; } if (nev->result == ISC_R_CANCELED) { NOTICE("accept canceled, goto out"); goto out; } if (nev->result != ISC_R_SUCCESS) { /* XXXMLG log failure */ NOTICE("accept returned failure, goto requeue"); goto requeue; } (void)isc_socket_getpeername(nev->newsocket, &peeraddr); if (httpdmgr->client_ok != NULL && !(httpdmgr->client_ok)(&peeraddr, httpdmgr->cb_arg)) { isc_socket_detach(&nev->newsocket); goto requeue; } httpd = isc_mem_get(httpdmgr->mctx, sizeof(isc_httpd_t)); if (httpd == NULL) { /* XXXMLG log failure */ NOTICE("accept failed to allocate memory, goto requeue"); isc_socket_detach(&nev->newsocket); goto requeue; } httpd->mgr = httpdmgr; ISC_LINK_INIT(httpd, link); ISC_LIST_APPEND(httpdmgr->running, httpd, link); ISC_HTTPD_SETRECV(httpd); httpd->sock = nev->newsocket; isc_socket_setname(httpd->sock, "httpd", NULL); httpd->flags = 0; /* * Initialize the buffer for our headers. */ httpd->headerdata = isc_mem_get(httpdmgr->mctx, HTTP_SENDGROW); if (httpd->headerdata == NULL) { isc_mem_put(httpdmgr->mctx, httpd, sizeof(isc_httpd_t)); isc_socket_detach(&nev->newsocket); goto requeue; } httpd->headerlen = HTTP_SENDGROW; isc_buffer_init(&httpd->headerbuffer, httpd->headerdata, httpd->headerlen); ISC_LIST_INIT(httpd->bufflist); isc_buffer_initnull(&httpd->bodybuffer); reset_client(httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; result = isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); /* FIXME!!! */ POST(result); NOTICE("accept queued recv on socket"); requeue: result = isc_socket_accept(httpdmgr->sock, task, isc_httpd_accept, httpdmgr); if (result != ISC_R_SUCCESS) { /* XXXMLG what to do? Log failure... */ NOTICE("accept could not reaccept due to failure"); } out: UNLOCK(&httpdmgr->lock); httpdmgr_destroy(httpdmgr); isc_event_free(&ev); EXIT("accept"); }
/*------------------------------------------------------------------------ * MAIN PROGRAM *------------------------------------------------------------------------*/ int main(int argc, const char *argv[]) { command_t command; /* the current command being processed */ //char command_text[MAX_COMMAND_LENGTH]; /* the raw text of the command */ char *command_text; ttp_session_t *session = NULL; ttp_parameter_t parameter; int argc_curr = 1; /* command line argument currently to be processed */ char *ptr_command_text = &command_text[0]; /* reset the client */ memset(¶meter, 0, sizeof(parameter)); reset_client(¶meter); /* show version / build information */ #ifdef VSIB_REALTIME fprintf(stderr, "Tsunami Realtime Client for protocol rev %X\nRevision: %s\nCompiled: %s %s\n" " /dev/vsib VSIB accesses mode is %d, gigabit=%d, 1pps embed=%d, sample skip=%d\n", PROTOCOL_REVISION, TSUNAMI_CVS_BUILDNR, __DATE__ , __TIME__, vsib_mode, vsib_mode_gigabit, vsib_mode_embed_1pps_markers, vsib_mode_skip_samples); #else fprintf(stderr, "Tsunami Client for protocol rev %X\nRevision: %s\nCompiled: %s %s\n", PROTOCOL_REVISION, TSUNAMI_CVS_BUILDNR, __DATE__ , __TIME__); #endif /* while the command loop is still running */ while (1) { /* retrieve the user's commands */ if (argc<=1 || argc_curr>=argc) { /* present the prompt */ fprintf(stdout, "tsunami> "); fflush(stdout); /* read next command */ if (fgets(command_text, MAX_COMMAND_LENGTH, stdin) == NULL) { error("Could not read command input"); } } else { // severe TODO: check that command_text appends do not over flow MAX_COMMAND_LENGTH... /* assemble next command from command line arguments */ for ( ; argc_curr<argc; argc_curr++) { // zero argument commands if (!strcasecmp(argv[argc_curr], "close") || !strcasecmp(argv[argc_curr], "quit") || !strcasecmp(argv[argc_curr], "exit") || !strcasecmp(argv[argc_curr], "bye") || !strcasecmp(argv[argc_curr], "help") || !strcasecmp(argv[argc_curr], "dir")) { strcpy(command_text, argv[argc_curr]); argc_curr += 1; break; } // single argument commands if (!strcasecmp(argv[argc_curr], "connect")) { if (argc_curr+1 < argc) { strcpy(ptr_command_text, argv[argc_curr]); strcat(command_text, " "); strcat(command_text, argv[argc_curr+1]); } else { fprintf(stderr, "Connect: no host specified\n"); exit(1); } argc_curr += 2; break; } /*__FINAL_PROJECT_START__ if (!strcasecmp(argv[argc_curr], "connect6")) { if (argc_curr+1 < argc) { strcpy(ptr_command_text, argv[argc_curr]); strcat(command_text, " "); strcat(command_text, argv[argc_curr+1]); } else { fprintf(stderr, "Connect: no host specified\n"); exit(1); } argc_curr += 2; break; } __FINAL_PROJECT_END __*/ if (!strcasecmp(argv[argc_curr], "get")) { if (argc_curr+1 < argc) { strcpy(ptr_command_text, argv[argc_curr]); strcat(command_text, " "); strcat(command_text, argv[argc_curr+1]); } else { fprintf(stderr, "Get: no file specified\n"); exit(1); } argc_curr += 2; break; } // double argument commands if (!strcasecmp(argv[argc_curr], "set")) { if (argc_curr+2 < argc) { strcpy(ptr_command_text, argv[argc_curr]); strcat(command_text, " "); strcat(command_text, argv[argc_curr+1]); strcat(command_text, " "); strcat(command_text, argv[argc_curr+2]); } else { fprintf(stderr, "Connect: no host specified\n"); exit(1); } argc_curr += 3; break; } // unknown commands, skip fprintf(stderr, "Unsupported command console command: %s\n", argv[argc_curr]); } } /* parse the command */ parse_command(&command, command_text); /* make sure we have at least one word */ if (command.count == 0) continue; /* dispatch on the command type */ if (!strcasecmp(command.text[0], "close")) command_close (&command, session); else if (!strcasecmp(command.text[0], "connect")) session = command_connect(&command, ¶meter); //else if (!strcasecmp(command.text[0], "connect6")) session = command_connect6(&command, ¶meter); else if (!strcasecmp(command.text[0], "get")) command_get (&command, session); else if (!strcasecmp(command.text[0], "dir")) command_dir (&command, session); else if (!strcasecmp(command.text[0], "help")) command_help (&command, session); else if (!strcasecmp(command.text[0], "quit")) command_quit (&command, session); else if (!strcasecmp(command.text[0], "exit")) command_quit (&command, session); else if (!strcasecmp(command.text[0], "bye")) command_quit (&command, session); else if (!strcasecmp(command.text[0], "set")) command_set (&command, ¶meter); else fprintf(stderr, "Unrecognized command: '%s'. Use 'HELP' for help.\n\n", command.text[0]); } /* if we're here, we shouldn't be */ return 1; }
static void respond_to_client(struct server *s, struct client *c) { struct frame *f; size_t flen; ssize_t len; char buf[SERVER_BUFFER_SIZE]; if (!c->request_received || c->request == REQUEST_INCOMPLETE) { return; } // Serve response in the client's resp buffer if (c->resp_pos < c->resp_len - 1) { if ((len = client_write(c, &c->resp[c->resp_pos], c->resp_len - c->resp_pos)) > 0) { c->resp_pos += len; } c->last_communication = gettime(); return; } // Serve static file if (c->request == REQUEST_STATIC_FILE) { if ((flen = fread(buf, sizeof(char), sizeof(buf), c->static_file)) < 1) { // File is done, reset client for next request if (feof(c->static_file)) { reset_client(c); } return; } if ((len = client_write(c, buf, flen)) < 0) { if (errno == EINTR) { fseek(c->static_file, len, SEEK_CUR); // Rewind, as if we never read the file return; } return remove_client(s, c); } c->last_communication = gettime(); if (len < flen) { fseek(c->static_file, len - flen, SEEK_CUR); // Rewind by how much of the file we did not send } return; } // Serve stream else if (c->request == REQUEST_STREAM) { if ((f = get_frame(c->fb, c->current_frame)) == NULL) { // The client is very far behind. Catch them up c->current_frame = c->fb->current_frame; c->current_frame_pos = 0; f = get_frame(c->fb, c->current_frame); if (f == NULL) { return; // This frame literally does not exist yet } } if (c->current_frame < c->fb->current_frame || (c->current_frame == c->fb->current_frame && c->current_frame_pos < f->data_len)) { len = client_write(c, &f->data[c->current_frame_pos], f->data_len - c->current_frame_pos); if (len < 0) { if (errno == EINTR) { return; } return remove_client(s, c); } c->last_communication = gettime(); c->current_frame_pos += len; if (c->current_frame_pos == f->data_len) { // Catch them up to the latest frame c->current_frame = c->fb->current_frame; c->current_frame_pos = 0; } } } // Response was just in the c->resp buffer, so we are done else { return remove_client(s, c); } }