/* --- PRIVATE FUNCTIONS ---------------------------------------------------- */ static void CallbackBuildDnCache( _In_ CSV_HANDLE hOutfile, _In_ CSV_HANDLE hDenyOutfile, _In_ LPTSTR *tokens ) { BOOL bResult = FALSE; CACHE_OBJECT_BY_DN cacheEntry = { 0 }; CACHE_OBJECT_BY_DN mailCacheEntry = { 0 }; PCACHE_OBJECT_BY_DN inserted = NULL; BOOL newElement = FALSE; LPTSTR objectClass = NULL; UNREFERENCED_PARAMETER(hDenyOutfile); if (STR_EMPTY(tokens[LdpListDn]) || STR_EMPTY(tokens[LdpListObjectClass])) return; cacheEntry.dn = _tcsdup(tokens[LdpListDn]); if (!cacheEntry.dn) FATAL(_T("Could not dup dn <%s>"), tokens[LdpListDn]); cacheEntry.objectClass = _tcsdup(tokens[LdpListObjectClass]); if (!cacheEntry.objectClass) FATAL(_T("Could not dup objectClass <%s>"), tokens[LdpListObjectClass]); CacheEntryInsert( ppCache, (PVOID)&cacheEntry, sizeof(CACHE_OBJECT_BY_DN), &inserted, &newElement ); if (!inserted) { LOG(Err, _T("cannot insert new object-by-dn cache entry <%s>"), tokens[LdpListDn]); } else if (!newElement) { LOG(Dbg, _T("object-by-dn cache entry is not new <%s>"), tokens[LdpListDn]); free(cacheEntry.dn); free(cacheEntry.objectClass); } else { objectClass = _tcsrchr(tokens[LdpListObjectClass], _T(';')) + 1; bResult = ControlWriteOutline(hOutfile, tokens[LdpListDn], objectClass, CONTROL_ALLNODES_KEYWORD); if (!bResult) LOG(Err, _T("Cannot write outline for <%s>"), tokens[LdpListDn]); } // Writing Mail attributes as object of type email if (STR_EMPTY(tokens[LdpListMail])) return; mailCacheEntry.dn = _tcsdup(tokens[LdpListMail]); if (!mailCacheEntry.dn) FATAL(_T("Could not dup dn <%s>"), tokens[LdpListMail]); mailCacheEntry.objectClass = _tcsdup(_T("email")); if (!mailCacheEntry.objectClass) FATAL(_T("Could not dup objectClass <%s>"), _T("email")); CacheEntryInsert( ppCache, (PVOID)&mailCacheEntry, sizeof(CACHE_OBJECT_BY_DN), &inserted, &newElement ); if (!inserted) { LOG(Err, _T("cannot insert new object-by-dn cache entry <%s>"), tokens[LdpListMail]); } else if (!newElement) { LOG(Dbg, _T("object-by-dn cache entry is not new <%s>"), tokens[LdpListMail]); free(mailCacheEntry.dn); free(mailCacheEntry.objectClass); } else { bResult = ControlWriteOutline(hOutfile, tokens[LdpListMail], _T("email"), CONTROL_ALLNODES_KEYWORD); if (!bResult) LOG(Err, _T("Cannot write outline for <%s>"), tokens[LdpListMail]); } }
int main (int argc, char **argv) { int i, c; int pid_flags = 0; char *password = NULL; char *timeout = NULL; char *method = NULL; char *pid_path = NULL; char *conf_path = NULL; char *iface = NULL; int server_num = 0; char *server_host[MAX_REMOTE_NUM]; char *server_port = NULL; int dns_thread_num = DNS_THREAD_NUM; opterr = 0; while ((c = getopt (argc, argv, "f:s:p:l:k:t:m:c:i:d:v")) != -1) { switch (c) { case 's': server_host[server_num++] = optarg; break; case 'p': server_port = optarg; break; case 'k': password = optarg; break; case 'f': pid_flags = 1; pid_path = optarg; break; case 't': timeout = optarg; break; case 'm': method = optarg; break; case 'c': conf_path = optarg; break; case 'i': iface = optarg; break; case 'd': dns_thread_num = atoi(optarg); if (!dns_thread_num) FATAL("Invalid DNS thread number"); break; case 'v': verbose = 1; break; } } if (opterr) { usage(); exit(EXIT_FAILURE); } if (conf_path != NULL) { jconf_t *conf = read_jconf(conf_path); if (server_num == 0) { server_num = conf->remote_num; for (i = 0; i < server_num; i++) { server_host[i] = conf->remote_host[i]; } } if (server_port == NULL) server_port = conf->remote_port; if (password == NULL) password = conf->password; if (method == NULL) method = conf->method; if (timeout == NULL) timeout = conf->timeout; } if (server_num == 0 || server_port == NULL || password == NULL) { usage(); exit(EXIT_FAILURE); } if (timeout == NULL) timeout = "60"; if (pid_flags) { demonize(pid_path); } // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGCHLD, SIG_IGN); signal(SIGABRT, SIG_IGN); // setup asyncns asyncns_t *asyncns; if (!(asyncns = asyncns_new(dns_thread_num))) { FATAL("asyncns failed"); } // setup keys LOGD("initialize cihpers... %s", method); int m = enc_init(password, method); // inilitialize ev loop struct ev_loop *loop = EV_DEFAULT; // bind to each interface while (server_num > 0) { int index = --server_num; const char* host = server_host[index]; // Bind to port int listenfd; listenfd = create_and_bind(host, server_port); if (listenfd < 0) { FATAL("bind() error.."); } if (listen(listenfd, SOMAXCONN) == -1) { FATAL("listen() error."); } setnonblocking(listenfd); LOGD("server listening at port %s.", server_port); // Setup proxy context struct listen_ctx *listen_ctx = malloc(sizeof(struct listen_ctx)); listen_ctx->timeout = atoi(timeout); listen_ctx->asyncns = asyncns; listen_ctx->fd = listenfd; listen_ctx->method = m; listen_ctx->iface = iface; ev_io_init (&listen_ctx->io, accept_cb, listenfd, EV_READ); ev_io_start (loop, &listen_ctx->io); } // start ev loop ev_run (loop, 0); return 0; }
int main(int argc, char **argv) { int i, c; int pid_flags = 0; char *user = NULL; char *local_port = NULL; char *local_addr = NULL; char *password = NULL; char *timeout = NULL; char *method = NULL; char *pid_path = NULL; char *conf_path = NULL; int remote_num = 0; ss_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; opterr = 0; while ((c = getopt(argc, argv, "f:s:p:l:k:t:m:c:b:a:n:uUvA")) != -1) switch (c) { case 's': if (remote_num < MAX_REMOTE_NUM) { remote_addr[remote_num].host = optarg; remote_addr[remote_num++].port = NULL; } break; case 'p': remote_port = optarg; break; case 'l': local_port = optarg; break; case 'k': password = optarg; break; case 'f': pid_flags = 1; pid_path = optarg; break; case 't': timeout = optarg; break; case 'm': method = optarg; break; case 'c': conf_path = optarg; break; case 'b': local_addr = optarg; break; case 'a': user = optarg; break; #ifdef HAVE_SETRLIMIT case 'n': nofile = atoi(optarg); break; #endif case 'u': mode = TCP_AND_UDP; break; case 'U': mode = UDP_ONLY; break; case 'v': verbose = 1; break; case 'A': auth = 1; break; } if (opterr) { usage(); exit(EXIT_FAILURE); } if (argc == 1) { if (conf_path == NULL) { conf_path = DEFAULT_CONF_PATH; } } if (conf_path != NULL) { jconf_t *conf = read_jconf(conf_path); if (remote_num == 0) { remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) remote_addr[i] = conf->remote_addr[i]; } if (remote_port == NULL) { remote_port = conf->remote_port; } if (local_addr == NULL) { local_addr = conf->local_addr; } if (local_port == NULL) { local_port = conf->local_port; } if (password == NULL) { password = conf->password; } if (method == NULL) { method = conf->method; } if (timeout == NULL) { timeout = conf->timeout; } if (auth == 0) { auth = conf->auth; } #ifdef HAVE_SETRLIMIT if (nofile == 0) { nofile = conf->nofile; } /* * no need to check the return value here since we will show * the user an error message if setrlimit(2) fails */ if (nofile > 1024) { if (verbose) { LOGI("setting NOFILE to %d", nofile); } set_nofile(nofile); } #endif } if (remote_num == 0 || remote_port == NULL || local_port == NULL || password == NULL) { usage(); exit(EXIT_FAILURE); } if (timeout == NULL) { timeout = "60"; } if (local_addr == NULL) { local_addr = "127.0.0.1"; } if (pid_flags) { USE_SYSLOG(argv[0]); daemonize(pid_path); } if (auth) { LOGI("onetime authentication enabled"); } // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGABRT, SIG_IGN); // Setup keys LOGI("initialize ciphers... %s", method); int m = enc_init(password, method); // Setup proxy context listen_ctx_t listen_ctx; listen_ctx.remote_num = remote_num; listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *) * remote_num); for (int i = 0; i < remote_num; i++) { char *host = remote_addr[i].host; char *port = remote_addr[i].port == NULL ? remote_port : remote_addr[i].port; struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); if (get_sockaddr(host, port, storage, 1) == -1) { FATAL("failed to resolve the provided hostname"); } listen_ctx.remote_addr[i] = (struct sockaddr *)storage; } listen_ctx.timeout = atoi(timeout); listen_ctx.method = m; struct ev_loop *loop = EV_DEFAULT; if (mode != UDP_ONLY) { // Setup socket int listenfd; listenfd = create_and_bind(local_addr, local_port); if (listenfd < 0) { FATAL("bind() error"); } if (listen(listenfd, SOMAXCONN) == -1) { FATAL("listen() error"); } setnonblocking(listenfd); listen_ctx.fd = listenfd; ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ); ev_io_start(loop, &listen_ctx.io); } // Setup UDP if (mode != TCP_ONLY) { LOGI("UDP relay enabled"); init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0], get_sockaddr_len(listen_ctx.remote_addr[0]), m, auth, listen_ctx.timeout, NULL); } if (mode == UDP_ONLY) { LOGI("TCP relay disabled"); } LOGI("listening at %s:%s", local_addr, local_port); // setuid if (user != NULL) { run_as(user); } ev_run(loop, 0); return 0; }
static void process_req(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { write_req_t* wr; dnshandle* dns = (dnshandle*)handle; char hdrbuf[DNSREC_LEN]; int hdrbuf_remaining = DNSREC_LEN; int rec_remaining = 0; int readbuf_remaining; char* dnsreq; char* hdrstart; int usingprev = 0; wr = (write_req_t*) malloc(sizeof *wr); wr->buf.base = (char*)malloc(WRITE_BUF_LEN); wr->buf.len = 0; if (dns->state.prevbuf_ptr != NULL) { dnsreq = dns->state.prevbuf_ptr + dns->state.prevbuf_pos; readbuf_remaining = dns->state.prevbuf_rem; usingprev = 1; } else { dnsreq = buf->base; readbuf_remaining = nread; } hdrstart = dnsreq; while (dnsreq != NULL) { /* something to process */ while (readbuf_remaining > 0) { /* something to process in current buffer */ if (hdrbuf_remaining > 0) { /* process len and id */ if (readbuf_remaining < hdrbuf_remaining) { /* too little to get request header. save for next buffer */ memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], dnsreq, readbuf_remaining); hdrbuf_remaining = DNSREC_LEN - readbuf_remaining; break; } else { /* save header */ memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], dnsreq, hdrbuf_remaining); dnsreq += hdrbuf_remaining; readbuf_remaining -= hdrbuf_remaining; hdrbuf_remaining = 0; /* get record length */ rec_remaining = (unsigned) hdrbuf[0] * 256 + (unsigned) hdrbuf[1]; rec_remaining -= (DNSREC_LEN - 2); } } if (rec_remaining <= readbuf_remaining) { /* prepare reply */ addrsp(wr, hdrbuf); /* move to next record */ dnsreq += rec_remaining; hdrstart = dnsreq; readbuf_remaining -= rec_remaining; rec_remaining = 0; hdrbuf_remaining = DNSREC_LEN; } else { /* otherwise this buffer is done. */ rec_remaining -= readbuf_remaining; break; } } /* If we had to use bytes from prev buffer, start processing the current * one. */ if (usingprev == 1) { /* free previous buffer */ free(dns->state.prevbuf_ptr); dnsreq = buf->base; readbuf_remaining = nread; usingprev = 0; } else { dnsreq = NULL; } } /* send write buffer */ if (wr->buf.len > 0) { if (uv_write((uv_write_t*) &wr->req, handle, &wr->buf, 1, after_write)) { FATAL("uv_write failed"); } } if (readbuf_remaining > 0) { /* save start of record position, so we can continue on next read */ dns->state.prevbuf_ptr = buf->base; dns->state.prevbuf_pos = hdrstart - buf->base; dns->state.prevbuf_rem = nread - dns->state.prevbuf_pos; } else { /* nothing left in this buffer */ dns->state.prevbuf_ptr = NULL; dns->state.prevbuf_pos = 0; dns->state.prevbuf_rem = 0; free(buf->base); } }
static void server_recv_cb (EV_P_ ev_io *w, int revents) { struct server_ctx *server_recv_ctx = (struct server_ctx *)w; struct server *server = server_recv_ctx->server; struct remote *remote = NULL; int len = server->buf_len; char **buf = &server->buf; ev_timer_again(EV_A_ &server->recv_ctx->watcher); if (server->stage != 0) { remote = server->remote; buf = &remote->buf; len = 0; } ssize_t r = recv(server->fd, *buf + len, BUF_SIZE - len, 0); if (r == 0) { // connection closed if (verbose) { LOGD("server_recv close the connection"); } close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; } else if (r == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // no data // continue to wait for recv return; } else { ERROR("server recv"); close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; } } // handle incomplete header if (server->stage == 0) { r += server->buf_len; if (r <= enc_get_iv_len()) { // wait for more if (verbose) { LOGD("imcomplete header: %zu", r); } server->buf_len = r; return; } else { server->buf_len = 0; } } *buf = ss_decrypt(*buf, &r, server->d_ctx); if (*buf == NULL) { LOGE("invalid password or cipher"); close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); return; } // handshake and transmit data if (server->stage == 5) { int s = send(remote->fd, remote->buf, r, 0); if (s == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // no data, wait for send remote->buf_len = r; remote->buf_idx = 0; ev_io_stop(EV_A_ &server_recv_ctx->io); ev_io_start(EV_A_ &remote->send_ctx->io); } else { ERROR("server_recv_send"); close_and_free_remote(EV_A_ remote); close_and_free_server(EV_A_ server); } } else if (s < r) { remote->buf_len = r - s; remote->buf_idx = s; ev_io_stop(EV_A_ &server_recv_ctx->io); ev_io_start(EV_A_ &remote->send_ctx->io); } return; } else if (server->stage == 0) { /* * Shadowsocks Protocol: * * +------+----------+----------+ * | ATYP | DST.ADDR | DST.PORT | * +------+----------+----------+ * | 1 | Variable | 2 | * +------+----------+----------+ */ int offset = 0; char atyp = server->buf[offset++]; char host[256]; char port[64]; memset(host, 0, 256); int p = 0; // get remote addr and port if (atyp == 1) { // IP V4 size_t in_addr_len = sizeof(struct in_addr); if (r > in_addr_len) { inet_ntop(AF_INET, (const void *)(server->buf + offset), host, INET_ADDRSTRLEN); offset += in_addr_len; } } else if (atyp == 3) { // Domain name uint8_t name_len = *(uint8_t *)(server->buf + offset); if (name_len < r && name_len < 255 && name_len > 0) { memcpy(host, server->buf + offset + 1, name_len); offset += name_len + 1; } } else if (atyp == 4) { // IP V6 size_t in6_addr_len = sizeof(struct in6_addr); if (r > in6_addr_len) { inet_ntop(AF_INET6, (const void*)(server->buf + offset), host, INET6_ADDRSTRLEN); offset += in6_addr_len; } } if (offset == 1) { LOGE("invalid header with addr type %d", atyp); close_and_free_server(EV_A_ server); return; } p = ntohs(*(uint16_t *)(server->buf + offset)); offset += 2; sprintf(port, "%d", p); if (verbose) { LOGD("connect to: %s:%s", host, port); } struct addrinfo hints; asyncns_query_t *query; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; query = asyncns_getaddrinfo(server->listen_ctx->asyncns, host, port, &hints); if (query == NULL) { ERROR("asyncns_getaddrinfo"); close_and_free_server(EV_A_ server); return; } // XXX: should handle buffer carefully if (r > offset) { server->buf_len = r - offset; server->buf_idx = offset; } server->stage = 4; server->query = query; ev_io_stop(EV_A_ &server_recv_ctx->io); ev_timer_start(EV_A_ &server->send_ctx->watcher); return; } // should not reach here FATAL("server context error."); }
int getrec(char **pbuf, int *pbufsize, int isrecord) /* get next input record */ { /* note: cares whether buf == record */ int c; char *buf = *pbuf; uschar saveb0; int bufsize = *pbufsize, savebufsize = bufsize; if (awk_firsttime) { awk_firsttime = 0; initgetrec(); } dprintf( ("RS=<%s>, FS=<%s>, ARGC=%g, FILENAME=%s\n", *RS, *FS, *ARGC, *FILENAME) ); if (isrecord) { donefld = 0; donerec = 1; } saveb0 = buf[0]; buf[0] = 0; while (argno < *ARGC || infile == stdin) { dprintf( ("argno=%d, file=|%s|\n", argno, file) ); if (infile == NULL) { /* have to open a new file */ file = getargv(argno); if (*file == '\0') { /* it's been zapped */ argno++; continue; } if (isclvar(file)) { /* a var=value arg */ setclvar(file); argno++; continue; } *FILENAME = file; dprintf( ("opening file %s\n", file) ); if (*file == '-' && *(file+1) == '\0') infile = stdin; else if ((infile = fopen(file, "r")) == NULL) FATAL("can't open file %s", file); setfval(fnrloc, 0.0); } c = readrec(&buf, &bufsize, infile); if (c != 0 || buf[0] != '\0') { /* normal record */ if (isrecord) { if (freeable(fldtab[0])) xfree(fldtab[0]->sval); fldtab[0]->sval = buf; /* buf == record */ fldtab[0]->tval = REC | STR | DONTFREE; if (is_number(fldtab[0]->sval)) { fldtab[0]->fval = atof(fldtab[0]->sval); fldtab[0]->tval |= NUM; } } setfval(nrloc, nrloc->fval+1); setfval(fnrloc, fnrloc->fval+1); if (donefld == 0) fldbld(); *pbuf = buf; *pbufsize = bufsize; return 1; } /* EOF arrived on this file; set up next */ if (infile != stdin) fclose(infile); infile = NULL; argno++; } buf[0] = saveb0; *pbuf = buf; *pbufsize = savebufsize; return 0; /* true end of file */ }
void fpecatch(int n) { FATAL("floating point exception %d", n); }
int run_test(const char* test, int timeout, int benchmark_output) { char errmsg[1024] = "no error"; process_info_t processes[1024]; process_info_t *main_proc; task_entry_t* task; int process_count; int result; int status; int i; status = 255; main_proc = NULL; process_count = 0; #ifndef _WIN32 /* Clean up stale socket from previous run. */ remove(TEST_PIPENAME); #endif /* If it's a helper the user asks for, start it directly. */ for (task = TASKS; task->main; task++) { if (task->is_helper && strcmp(test, task->process_name) == 0) { return task->main(); } } /* Start the helpers first. */ for (task = TASKS; task->main; task++) { if (strcmp(test, task->task_name) != 0) { continue; } /* Skip the test itself. */ if (!task->is_helper) { continue; } if (process_start(task->task_name, task->process_name, &processes[process_count]) == -1) { snprintf(errmsg, sizeof errmsg, "Process `%s` failed to start.", task->process_name); goto out; } process_count++; } /* Give the helpers time to settle. Race-y, fix this. */ uv_sleep(250); /* Now start the test itself. */ for (task = TASKS; task->main; task++) { if (strcmp(test, task->task_name) != 0) { continue; } if (task->is_helper) { continue; } if (process_start(task->task_name, task->process_name, &processes[process_count]) == -1) { snprintf(errmsg, sizeof errmsg, "Process `%s` failed to start.", task->process_name); goto out; } main_proc = &processes[process_count]; process_count++; break; } if (main_proc == NULL) { snprintf(errmsg, sizeof errmsg, "No test with that name: %s", test); goto out; } result = process_wait(main_proc, 1, timeout); if (result == -1) { FATAL("process_wait failed"); } else if (result == -2) { /* Don't have to clean up the process, process_wait() has killed it. */ snprintf(errmsg, sizeof errmsg, "timeout"); goto out; } status = process_reap(main_proc); if (status != 0) { snprintf(errmsg, sizeof errmsg, "exit code %d", status); goto out; } if (benchmark_output) { /* Give the helpers time to clean up their act. */ uv_sleep(1000); } out: /* Reap running processes except the main process, it's already dead. */ for (i = 0; i < process_count - 1; i++) { process_terminate(&processes[i]); } if (process_count > 0 && process_wait(processes, process_count - 1, -1) < 0) { FATAL("process_wait failed"); } /* Show error and output from processes if the test failed. */ if (status != 0 || task->show_output) { if (status != 0) { LOGF("\n`%s` failed: %s\n", test, errmsg); } else { LOGF("\n"); } for (i = 0; i < process_count; i++) { switch (process_output_size(&processes[i])) { case -1: LOGF("Output from process `%s`: (unavailable)\n", process_get_name(&processes[i])); break; case 0: LOGF("Output from process `%s`: (no output)\n", process_get_name(&processes[i])); break; default: LOGF("Output from process `%s`:\n", process_get_name(&processes[i])); process_copy_output(&processes[i], fileno(stderr)); break; } } LOG("=============================================================\n"); /* In benchmark mode show concise output from the main process. */ } else if (benchmark_output) { switch (process_output_size(main_proc)) { case -1: LOGF("%s: (unavailable)\n", test); break; case 0: LOGF("%s: (no output)\n", test); break; default: for (i = 0; i < process_count; i++) { process_copy_output(&processes[i], fileno(stderr)); } break; } } /* Clean up all process handles. */ for (i = 0; i < process_count; i++) { process_cleanup(&processes[i]); } return status; }
int main(int argc, char *argv[]) { char *dir = NULL; VMEM *vmp; START(argc, argv, "vmem_freespace"); if (argc == 2) { dir = argv[1]; } else if (argc > 2) { FATAL("usage: %s [directory]", argv[0]); } if (dir == NULL) { /* allocate memory for function vmem_pool_create_in_region() */ void *mem_pool = MMAP(NULL, VMEM_MIN_POOL, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); vmp = vmem_pool_create_in_region(mem_pool, VMEM_MIN_POOL); if (vmp == NULL) FATAL("!vmem_pool_create_in_region"); } else { vmp = vmem_pool_create(dir, VMEM_MIN_POOL); if (vmp == NULL) FATAL("!vmem_pool_create"); } size_t total_space = vmem_pool_freespace(vmp); size_t free_space = total_space; /* allocate all memory */ void *prev = NULL; void **next; while ((next = vmem_malloc(vmp, 128)) != NULL) { *next = prev; prev = next; size_t space = vmem_pool_freespace(vmp); /* free space can only decrease */ ASSERT(space <= free_space); free_space = space; } ASSERTne(prev, NULL); /* for small allocations use all memory */ ASSERTeq(free_space, 0); while (prev != NULL) { void **act = prev; prev = *act; vmem_free(vmp, act); size_t space = vmem_pool_freespace(vmp); /* free space can only increase */ ASSERT(space >= free_space); free_space = space; } free_space = vmem_pool_freespace(vmp); /* * Depending on the distance of the 'mem_pool' from the * chunk alignment (4MB) a different size of free memory * will be wasted on base_alloc inside jemalloc. * Rest of the internal data should not waste more than 10% of space. */ ASSERT(free_space > ((total_space - 4L * MB) * 9) / 10); vmem_pool_delete(vmp); DONE(NULL); }
void read_config(u8* fname) { s32 f; struct stat st; u8 *data, *cur; f = open((char*)fname, O_RDONLY); if (f < 0) PFATAL("Cannot open '%s' for reading.", fname); if (fstat(f, &st)) PFATAL("fstat() on '%s' failed.", fname); if (!st.st_size) { close(f); goto end_fp_read; } cur = data = ck_alloc(st.st_size + 1); if (read(f, data, st.st_size) != st.st_size) FATAL("Short read from '%s'.", fname); data[st.st_size] = 0; close(f); /* If you put NUL in your p0f.fp... Well, sucks to be you. */ while (1) { u8 *eol; line_no++; while (isblank(*cur)) cur++; eol = cur; while (*eol && *eol != '\n') eol++; if (*cur != ';' && cur != eol) { u8* line = ck_memdup_str(cur, eol - cur); config_parse_line(line); ck_free(line); } if (!*eol) break; cur = eol + 1; } ck_free(data); end_fp_read: if (!sig_cnt) SAYF("[!] No signatures found in '%s'.\n", fname); else SAYF("[+] Loaded %u signature%s from '%s'.\n", sig_cnt, sig_cnt == 1 ? "" : "s", fname); }
int main(int argc, char **argv) { int i, c; int pid_flags = 0; char *user = NULL; char *local_port = NULL; char *local_addr = NULL; char *password = NULL; char *timeout = NULL; char *method = NULL; char *pid_path = NULL; char *conf_path = NULL; char *iface = NULL; srand(time(NULL)); int remote_num = 0; ss_addr_t remote_addr[MAX_REMOTE_NUM]; char *remote_port = NULL; int option_index = 0; static struct option long_options[] = { { "fast-open", no_argument, 0, 0 }, { "acl", required_argument, 0, 0 }, { 0, 0, 0, 0 } }; opterr = 0; USE_TTY(); #ifdef ANDROID while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:uvVA", long_options, &option_index)) != -1) { #else while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:uvA", long_options, &option_index)) != -1) { #endif switch (c) { case 0: if (option_index == 0) { fast_open = 1; } else if (option_index == 1) { LOGI("initialize acl..."); acl = !init_acl(optarg); } break; case 's': if (remote_num < MAX_REMOTE_NUM) { remote_addr[remote_num].host = optarg; remote_addr[remote_num++].port = NULL; } break; case 'p': remote_port = optarg; break; case 'l': local_port = optarg; break; case 'k': password = optarg; break; case 'f': pid_flags = 1; pid_path = optarg; break; case 't': timeout = optarg; break; case 'm': method = optarg; break; case 'c': conf_path = optarg; break; case 'i': iface = optarg; break; case 'b': local_addr = optarg; break; case 'a': user = optarg; break; case 'u': mode = TCP_AND_UDP; break; case 'v': verbose = 1; break; case 'A': auth = 1; break; #ifdef ANDROID case 'V': vpn = 1; break; #endif } } if (opterr) { usage(); exit(EXIT_FAILURE); } if (argc == 1) { if (conf_path == NULL) { conf_path = DEFAULT_CONF_PATH; } } if (conf_path != NULL) { jconf_t *conf = read_jconf(conf_path); if (remote_num == 0) { remote_num = conf->remote_num; for (i = 0; i < remote_num; i++) { remote_addr[i] = conf->remote_addr[i]; } } if (remote_port == NULL) { remote_port = conf->remote_port; } if (local_addr == NULL) { local_addr = conf->local_addr; } if (local_port == NULL) { local_port = conf->local_port; } if (password == NULL) { password = conf->password; } if (method == NULL) { method = conf->method; } if (timeout == NULL) { timeout = conf->timeout; } if (fast_open == 0) { fast_open = conf->fast_open; } #ifdef HAVE_SETRLIMIT if (nofile == 0) { nofile = conf->nofile; } /* * no need to check the return value here since we will show * the user an error message if setrlimit(2) fails */ if (nofile) { if (verbose) { LOGI("setting NOFILE to %d", nofile); } set_nofile(nofile); } #endif } if (remote_num == 0 || remote_port == NULL || local_port == NULL || password == NULL) { usage(); exit(EXIT_FAILURE); } if (timeout == NULL) { timeout = "60"; } if (local_addr == NULL) { local_addr = "127.0.0.1"; } if (pid_flags) { USE_SYSLOG(argv[0]); daemonize(pid_path); } if (fast_open == 1) { #ifdef TCP_FASTOPEN LOGI("using tcp fast open"); #else LOGE("tcp fast open is not supported by this environment"); #endif } if (auth) { LOGI("onetime authentication enabled"); } #ifdef __MINGW32__ winsock_init(); #else // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGABRT, SIG_IGN); #endif struct ev_signal sigint_watcher; struct ev_signal sigterm_watcher; ev_signal_init(&sigint_watcher, signal_cb, SIGINT); ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM); ev_signal_start(EV_DEFAULT, &sigint_watcher); ev_signal_start(EV_DEFAULT, &sigterm_watcher); // Setup keys LOGI("initialize ciphers... %s", method); int m = enc_init(password, method); // Setup proxy context struct listen_ctx listen_ctx; listen_ctx.remote_num = remote_num; listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *) * remote_num); for (i = 0; i < remote_num; i++) { char *host = remote_addr[i].host; char *port = remote_addr[i].port == NULL ? remote_port : remote_addr[i].port; struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); if (get_sockaddr(host, port, storage, 1) == -1) { FATAL("failed to resolve the provided hostname"); } listen_ctx.remote_addr[i] = (struct sockaddr *)storage; } listen_ctx.timeout = atoi(timeout); listen_ctx.iface = iface; listen_ctx.method = m; struct ev_loop *loop = EV_DEFAULT; // Setup socket int listenfd; listenfd = create_and_bind(local_addr, local_port); if (listenfd < 0) { FATAL("bind() error"); } if (listen(listenfd, SOMAXCONN) == -1) { FATAL("listen() error"); } setnonblocking(listenfd); listen_ctx.fd = listenfd; ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ); ev_io_start(loop, &listen_ctx.io); // Setup UDP if (mode != TCP_ONLY) { LOGI("udprelay enabled"); init_udprelay(local_addr, local_port, listen_ctx.remote_addr[0], get_sockaddr_len(listen_ctx.remote_addr[0]), m, listen_ctx.timeout, iface); } LOGI("listening at %s:%s", local_addr, local_port); // setuid if (user != NULL) { run_as(user); } // Init connections cork_dllist_init(&connections); // Enter the loop ev_run(loop, 0); if (verbose) { LOGI("closed gracefully"); } // Clean up ev_io_stop(loop, &listen_ctx.io); free_connections(loop); if (mode != TCP_ONLY) { free_udprelay(); } for (i = 0; i < remote_num; i++) { free(listen_ctx.remote_addr[i]); } free(listen_ctx.remote_addr); #ifdef __MINGW32__ winsock_cleanup(); #endif ev_signal_stop(EV_DEFAULT, &sigint_watcher); ev_signal_stop(EV_DEFAULT, &sigterm_watcher); return 0; } #else int start_ss_local_server(profile_t profile) { srand(time(NULL)); char *remote_host = profile.remote_host; char *local_addr = profile.local_addr; char *method = profile.method; char *password = profile.password; char *log = profile.log; int remote_port = profile.remote_port; int local_port = profile.local_port; int timeout = profile.timeout; mode = profile.mode; fast_open = profile.fast_open; verbose = profile.verbose; char local_port_str[16]; char remote_port_str[16]; sprintf(local_port_str, "%d", local_port); sprintf(remote_port_str, "%d", remote_port); USE_LOGFILE(log); if (profile.acl != NULL) { acl = !init_acl(profile.acl); } if (local_addr == NULL) { local_addr = "127.0.0.1"; } #ifdef __MINGW32__ winsock_init(); #else // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); signal(SIGABRT, SIG_IGN); #endif struct ev_signal sigint_watcher; struct ev_signal sigterm_watcher; ev_signal_init(&sigint_watcher, signal_cb, SIGINT); ev_signal_init(&sigterm_watcher, signal_cb, SIGTERM); ev_signal_start(EV_DEFAULT, &sigint_watcher); ev_signal_start(EV_DEFAULT, &sigterm_watcher); // Setup keys LOGI("initialize ciphers... %s", method); int m = enc_init(password, method); struct sockaddr_storage *storage = malloc(sizeof(struct sockaddr_storage)); memset(storage, 0, sizeof(struct sockaddr_storage)); if (get_sockaddr(remote_host, remote_port_str, storage, 1) == -1) { return -1; } // Setup proxy context struct ev_loop *loop = EV_DEFAULT; struct listen_ctx listen_ctx; listen_ctx.remote_num = 1; listen_ctx.remote_addr = malloc(sizeof(struct sockaddr *)); listen_ctx.remote_addr[0] = (struct sockaddr *)storage; listen_ctx.timeout = timeout; listen_ctx.method = m; listen_ctx.iface = NULL; // Setup socket int listenfd; listenfd = create_and_bind(local_addr, local_port_str); if (listenfd < 0) { ERROR("bind()"); return -1; } if (listen(listenfd, SOMAXCONN) == -1) { ERROR("listen()"); return -1; } setnonblocking(listenfd); listen_ctx.fd = listenfd; ev_io_init(&listen_ctx.io, accept_cb, listenfd, EV_READ); ev_io_start(loop, &listen_ctx.io); // Setup UDP if (mode != TCP_ONLY) { LOGI("udprelay enabled"); struct sockaddr *addr = (struct sockaddr *)storage; init_udprelay(local_addr, local_port_str, addr, get_sockaddr_len(addr), m, timeout, NULL); } LOGI("listening at %s:%s", local_addr, local_port_str); // Init connections cork_dllist_init(&connections); // Enter the loop ev_run(loop, 0); if (verbose) { LOGI("closed gracefully"); } // Clean up if (mode != TCP_ONLY) { free_udprelay(); } ev_io_stop(loop, &listen_ctx.io); free_connections(loop); close(listen_ctx.fd); free(listen_ctx.remote_addr); #ifdef __MINGW32__ winsock_cleanup(); #endif ev_signal_stop(EV_DEFAULT, &sigint_watcher); ev_signal_stop(EV_DEFAULT, &sigterm_watcher); // cannot reach here return 0; }
static void config_parse_line(u8* line) { u8 *val,*eon; /* Special handling for [module:direction]... */ if (*line == '[') { u8* dir; line++; /* Simplified case for [mtu]. */ if (!strcmp((char*)line, "mtu]")) { mod_type = CF_MOD_MTU; state = CF_NEED_LABEL; return; } dir = (u8*)strchr((char*)line, ':'); if (!dir) FATAL("Malformed section identifier in line %u.", line_no); *dir = 0; dir++; if (!strcmp((char*)line, "tcp")) { mod_type = CF_MOD_TCP; } else if (!strcmp((char*)line, "http")) { mod_type = CF_MOD_HTTP; } else if (!strcmp((char*)line, "ssl")) { mod_type = CF_MOD_SSL; } else { FATAL("Unrecognized fingerprinting module '%s' in line %u.", line, line_no); } if (!strcmp((char*)dir, "request]")) { mod_to_srv = 1; } else if (!strcmp((char*)dir, "response]")) { mod_to_srv = 0; } else { FATAL("Unrecognized traffic direction in line %u.", line_no); } state = CF_NEED_LABEL; return; } /* Everything else follows the 'name = value' approach. */ val = line; while (isalpha(*val) || *val == '_') val++; eon = val; while (isblank(*val)) val++; if (line == val || *val != '=') FATAL("Unexpected statement in line %u.", line_no); while (isblank(*++val)); *eon = 0; if (!strcmp((char*)line, "classes")) { if (state != CF_NEED_SECT) FATAL("misplaced 'classes' in line %u.", line_no); config_parse_classes(val); } else if (!strcmp((char*)line, "ua_os")) { if (state != CF_NEED_LABEL || mod_to_srv != 1 || mod_type != CF_MOD_HTTP) FATAL("misplaced 'us_os' in line %u.", line_no); http_parse_ua(val, line_no); } else if (!strcmp((char*)line, "label")) { /* We will drop sig_sys / sig_flavor on the floor if no signatures actually created, but it's not worth tracking that. */ if (state != CF_NEED_LABEL && state != CF_NEED_SIG) FATAL("misplaced 'label' in line %u.", line_no); config_parse_label(val); if (mod_type != CF_MOD_MTU && sig_class < 0) state = CF_NEED_SYS; else state = CF_NEED_SIG; } else if (!strcmp((char*)line, "sys")) { if (state != CF_NEED_SYS) FATAL("Misplaced 'sys' in line %u.", line_no); config_parse_sys(val); state = CF_NEED_SIG; } else if (!strcmp((char*)line, "sig")) { if (state != CF_NEED_SIG) FATAL("Misplaced 'sig' in line %u.", line_no); switch (mod_type) { case CF_MOD_TCP: tcp_register_sig(mod_to_srv, generic, sig_class, sig_name, sig_flavor, label_id, cur_sys, cur_sys_cnt, val, line_no); break; case CF_MOD_MTU: mtu_register_sig(sig_flavor, val, line_no); break; case CF_MOD_HTTP: http_register_sig(mod_to_srv, generic, sig_class, sig_name, sig_flavor, label_id, cur_sys, cur_sys_cnt, val, line_no); break; case CF_MOD_SSL: ssl_register_sig(mod_to_srv, generic, sig_class, sig_name, sig_flavor, label_id, cur_sys, cur_sys_cnt, val, line_no); break; } sig_cnt++; } else { FATAL("Unrecognized field '%s' in line %u.", line, line_no); } }
static void lSignal(void *) { FATAL("Unhandled signal sent to process; terminating."); }
static void fail_cb(void) { FATAL("fail_cb should not have been called"); }
static void never_cb(uv_timer_t* handle) { FATAL("never_cb should never be called"); }
void enc_key_init(int method, const char *pass) { if (method <= TABLE || method >= CIPHER_NUM) { LOGE("enc_key_init(): Illegal method"); return; } // Initialize cache cache_create(&iv_cache, 256, NULL); #if defined(USE_CRYPTO_OPENSSL) OpenSSL_add_all_algorithms(); #endif uint8_t iv[MAX_IV_LENGTH]; cipher_kt_t *cipher; cipher_kt_t cipher_info; if (method == SALSA20 || method == CHACHA20 || method == CHACHA20IETF) { if (sodium_init() == -1) { FATAL("Failed to initialize sodium"); } // Fake cipher cipher = (cipher_kt_t *)&cipher_info; #if defined(USE_CRYPTO_OPENSSL) cipher->key_len = supported_ciphers_key_size[method]; cipher->iv_len = supported_ciphers_iv_size[method]; #endif #if defined(USE_CRYPTO_POLARSSL) cipher->base = NULL; cipher->key_length = supported_ciphers_key_size[method] * 8; cipher->iv_size = supported_ciphers_iv_size[method]; #endif #if defined(USE_CRYPTO_MBEDTLS) // XXX: key_length changed to key_bitlen in mbed TLS 2.0.0 cipher->base = NULL; cipher->key_bitlen = supported_ciphers_key_size[method] * 8; cipher->iv_size = supported_ciphers_iv_size[method]; #endif } else { cipher = (cipher_kt_t *)get_cipher_type(method); } if (cipher == NULL) { do { #if defined(USE_CRYPTO_POLARSSL) && defined(USE_CRYPTO_APPLECC) if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) { cipher_info.base = NULL; cipher_info.key_length = supported_ciphers_key_size[method] * 8; cipher_info.iv_size = supported_ciphers_iv_size[method]; cipher = (cipher_kt_t *)&cipher_info; break; } #endif #if defined(USE_CRYPTO_MBEDTLS) && defined(USE_CRYPTO_APPLECC) // XXX: key_length changed to key_bitlen in mbed TLS 2.0.0 if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) { cipher_info.base = NULL; cipher_info.key_bitlen = supported_ciphers_key_size[method] * 8; cipher_info.iv_size = supported_ciphers_iv_size[method]; cipher = (cipher_kt_t *)&cipher_info; break; } #endif LOGE("Cipher %s not found in crypto library", supported_ciphers[method]); FATAL("Cannot initialize cipher"); } while (0); } const digest_type_t *md = get_digest_type("MD5"); if (md == NULL) { FATAL("MD5 Digest not found in crypto library"); } enc_key_len = bytes_to_key(cipher, md, (const uint8_t *)pass, enc_key, iv); if (enc_key_len == 0) { FATAL("Cannot generate key and IV"); } if (method == RC4_MD5 || method == RC4_MD5_6) { enc_iv_len = supported_ciphers_iv_size[method]; } else { enc_iv_len = cipher_iv_size(cipher); } enc_method = method; }
static void dummy_timeout_cb(oio_req *req) { /* Should never be called */ FATAL("dummy_timer_cb should never be called"); }
int rand_bytes(uint8_t *output, int len) { #if defined(USE_CRYPTO_OPENSSL) return RAND_bytes(output, len); #elif defined(USE_CRYPTO_POLARSSL) static entropy_context ec = {}; static ctr_drbg_context cd_ctx = {}; static unsigned char rand_initialised = 0; const size_t blen = min(len, CTR_DRBG_MAX_REQUEST); if (!rand_initialised) { #ifdef _WIN32 HCRYPTPROV hProvider; union { unsigned __int64 seed; BYTE buffer[8]; } rand_buffer; hProvider = 0; if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, \ CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { CryptGenRandom(hProvider, 8, rand_buffer.buffer); CryptReleaseContext(hProvider, 0); } else { rand_buffer.seed = (unsigned __int64)clock(); } #else FILE *urand; union { uint64_t seed; uint8_t buffer[8]; } rand_buffer; urand = fopen("/dev/urandom", "r"); if (urand) { int read = fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1, urand); fclose(urand); if (read <= 0) { rand_buffer.seed = (uint64_t)clock(); } } else { rand_buffer.seed = (uint64_t)clock(); } #endif entropy_init(&ec); if (ctr_drbg_init(&cd_ctx, entropy_func, &ec, (const unsigned char *)rand_buffer.buffer, 8) != 0) { #if POLARSSL_VERSION_NUMBER >= 0x01030000 entropy_free(&ec); #endif FATAL("Failed to initialize random generator"); } rand_initialised = 1; } while (len > 0) { if (ctr_drbg_random(&cd_ctx, output, blen) != 0) { return 0; } output += blen; len -= blen; } return 1; #elif defined(USE_CRYPTO_MBEDTLS) static mbedtls_entropy_context ec = {}; // XXX: ctr_drbg_context changed, [if defined(MBEDTLS_THREADING_C) mbedtls_threading_mutex_t mutex;] static mbedtls_ctr_drbg_context cd_ctx = {}; static unsigned char rand_initialised = 0; const size_t blen = min(len, MBEDTLS_CTR_DRBG_MAX_REQUEST); if (!rand_initialised) { #ifdef _WIN32 HCRYPTPROV hProvider; union { unsigned __int64 seed; BYTE buffer[8]; } rand_buffer; hProvider = 0; if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, \ CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { CryptGenRandom(hProvider, 8, rand_buffer.buffer); CryptReleaseContext(hProvider, 0); } else { rand_buffer.seed = (unsigned __int64)clock(); } #else FILE *urand; union { uint64_t seed; uint8_t buffer[8]; } rand_buffer; urand = fopen("/dev/urandom", "r"); if (urand) { int read = fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1, urand); fclose(urand); if (read <= 0) { rand_buffer.seed = (uint64_t)clock(); } } else { rand_buffer.seed = (uint64_t)clock(); } #endif mbedtls_entropy_init(&ec); // XXX: ctr_drbg_init changed, seems we should initialize it before calling mbedtls_ctr_drbg_seed() mbedtls_ctr_drbg_init(&cd_ctx); if (mbedtls_ctr_drbg_seed(&cd_ctx, mbedtls_entropy_func, &ec, (const unsigned char *)rand_buffer.buffer, 8) != 0) { mbedtls_entropy_free(&ec); FATAL("mbed TLS: Failed to initialize random generator"); } rand_initialised = 1; } while (len > 0) { if (mbedtls_ctr_drbg_random(&cd_ctx, output, blen) != 0) { return 0; } output += blen; len -= blen; } return 1; #endif }
void fldbld(void) /* create fields from current record */ { /* this relies on having fields[] the same length as $0 */ /* the fields are all stored in this one array with \0's */ char *r, *fr, sep; Cell *p; int i, j, n; if (donefld) return; if (!isstr(fldtab[0])) getsval(fldtab[0]); r = fldtab[0]->sval; n = strlen(r); if (n > fieldssize) { xfree(fields); if ((fields = (char *) malloc(n+1)) == NULL) FATAL("out of space for fields in fldbld %d", n); fieldssize = n; } fr = fields; i = 0; /* number of fields accumulated here */ if (strlen(inputFS) > 1) { /* it's a regular expression */ i = refldbld(r, inputFS); } else if ((sep = *inputFS) == ' ') { /* default whitespace */ for (i = 0; ; ) { while (*r == ' ' || *r == '\t' || *r == '\n') r++; if (*r == 0) break; i++; if (i > nfields) growfldtab(i); if (freeable(fldtab[i])) xfree(fldtab[i]->sval); fldtab[i]->sval = fr; fldtab[i]->tval = FLD | STR | DONTFREE; do *fr++ = *r++; while (*r != ' ' && *r != '\t' && *r != '\n' && *r != '\0'); *fr++ = 0; } *fr = 0; } else if ((sep = *inputFS) == 0) { /* new: FS="" => 1 char/field */ for (i = 0; *r != 0; r++) { char buf[2]; i++; if (i > nfields) growfldtab(i); if (freeable(fldtab[i])) xfree(fldtab[i]->sval); buf[0] = *r; buf[1] = 0; fldtab[i]->sval = tostring(buf); fldtab[i]->tval = FLD | STR; } *fr = 0; } else if (*r != 0) { /* if 0, it's a null field */ /* subtlecase : if length(FS) == 1 && length(RS > 0) * \n is NOT a field separator (cf awk book 61,84). * this variable is tested in the inner while loop. */ int rtest = '\n'; /* normal case */ if (strlen(*RS) > 0) rtest = '\0'; for (;;) { i++; if (i > nfields) growfldtab(i); if (freeable(fldtab[i])) xfree(fldtab[i]->sval); fldtab[i]->sval = fr; fldtab[i]->tval = FLD | STR | DONTFREE; while (*r != sep && *r != rtest && *r != '\0') /* \n is always a separator */ *fr++ = *r++; *fr++ = 0; if (*r++ == 0) break; } *fr = 0; } if (i > nfields) FATAL("record `%.30s...' has too many fields; can't happen", r); cleanfld(i+1, lastfld); /* clean out junk from previous record */ lastfld = i; donefld = 1; for (j = 1; j <= lastfld; j++) { p = fldtab[j]; if(is_number(p->sval)) { p->fval = atof(p->sval); p->tval |= NUM; } } setfval(nfloc, (Awkfloat) lastfld); if (dbg) { for (j = 0; j <= lastfld; j++) { p = fldtab[j]; printf("field %d (%s): |%s|\n", j, p->nval, p->sval); } } }
void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) { if (method <= TABLE || method >= CIPHER_NUM) { LOGE("cipher_context_init(): Illegal method"); return; } if (method >= SALSA20) { enc_iv_len = supported_ciphers_iv_size[method]; return; } const char *ciphername = supported_ciphers[method]; #if defined(USE_CRYPTO_APPLECC) cipher_cc_t *cc = &ctx->cc; cc->cryptor = NULL; cc->cipher = supported_ciphers_applecc[method]; if (cc->cipher == kCCAlgorithmInvalid) { cc->valid = kCCContextInvalid; } else { cc->valid = kCCContextValid; if (cc->cipher == kCCAlgorithmRC4) { cc->mode = kCCModeRC4; cc->padding = ccNoPadding; } else { cc->mode = kCCModeCFB; cc->padding = ccPKCS7Padding; } return; } #endif cipher_evp_t *evp = &ctx->evp; const cipher_kt_t *cipher = get_cipher_type(method); #if defined(USE_CRYPTO_OPENSSL) if (cipher == NULL) { LOGE("Cipher %s not found in OpenSSL library", ciphername); FATAL("Cannot initialize cipher"); } EVP_CIPHER_CTX_init(evp); if (!EVP_CipherInit_ex(evp, cipher, NULL, NULL, NULL, enc)) { LOGE("Cannot initialize cipher %s", ciphername); exit(EXIT_FAILURE); } if (!EVP_CIPHER_CTX_set_key_length(evp, enc_key_len)) { EVP_CIPHER_CTX_cleanup(evp); LOGE("Invalid key length: %d", enc_key_len); exit(EXIT_FAILURE); } if (method > RC4_MD5) { EVP_CIPHER_CTX_set_padding(evp, 1); } #elif defined(USE_CRYPTO_POLARSSL) if (cipher == NULL) { LOGE("Cipher %s not found in PolarSSL library", ciphername); FATAL("Cannot initialize PolarSSL cipher"); } if (cipher_init_ctx(evp, cipher) != 0) { FATAL("Cannot initialize PolarSSL cipher context"); } #elif defined(USE_CRYPTO_MBEDTLS) // XXX: mbedtls_cipher_setup future change // NOTE: Currently also clears structure. In future versions you will be required to call // mbedtls_cipher_init() on the structure first. // void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); if (cipher == NULL) { LOGE("Cipher %s not found in mbed TLS library", ciphername); FATAL("Cannot initialize mbed TLS cipher"); } mbedtls_cipher_init(evp); if (mbedtls_cipher_setup(evp, cipher) != 0) { FATAL("Cannot initialize mbed TLS cipher context"); } #endif }
bool parseURI(string stringUri, URI &uri) { /* * schema://[username[:password]@]host[:port][/[path[?parameters]]] */ LOG_URI("------------------------"); LOG_URI("stringUri: `%s`", STR(stringUri)); string fullUri; string fullUriWithAuth = stringUri; string scheme; string authentication; string username; string password; string hostPort; string host; string portString; uint16_t port = 0; bool portSpecified = false; string fullDocumentPathWithParameters; string fullDocumentPath; string fullParameters; string documentPath; string document; string documentWithFullParameters; Variant parameters; string::size_type cursor = 0; string::size_type pos = 0; //1. Reset uri.Reset(); //2. trim trim(stringUri); if (stringUri == "") { FATAL("Empty uri"); return false; } //2. Get the scheme and the default port pos = stringUri.find("://", cursor); if (pos == string::npos) { FATAL("Unable to determine scheme"); return false; } scheme = lowerCase(stringUri.substr(cursor, pos - cursor)); cursor = pos + 3; if (_schemeToPort.size() == 0) { _schemeToPort["http"] = 80; _schemeToPort["rtmpt"] = 80; _schemeToPort["rtmpte"] = 80; _schemeToPort["https"] = 443; _schemeToPort["rtmps"] = 443; _schemeToPort["rtsp"] = 554; _schemeToPort["rtmp"] = 1935; _schemeToPort["rtmpe"] = 1935; _schemeToPort["mms"] = 1755; } if (MAP_HAS1(_schemeToPort, scheme)) { port = _schemeToPort[scheme]; } // else { // FATAL("Scheme `%s` not supported", STR(scheme)); // return false; // } LOG_URI("scheme: %s; default port: %"PRIu16, STR(scheme), port); //3. get the authentication portion. the search starts from //where the scheme detection left and up to the first / character string::size_type limit = stringUri.find("/", cursor); bool hasAuthentication = false; pos = stringUri.find("@", cursor); if (pos != string::npos) { if (limit != string::npos) { hasAuthentication = pos<limit; } else { hasAuthentication = true; } } if (hasAuthentication) { authentication = stringUri.substr(cursor, pos - cursor); fullUri = stringUri.substr(0, cursor); fullUri += stringUri.substr(pos + 1); cursor = pos + 1; } else { fullUri = fullUriWithAuth; } if (authentication != "") { pos = authentication.find(":"); if (pos != string::npos) { username = authentication.substr(0, pos); password = authentication.substr(pos + 1); } else { username = authentication; password = ""; } } LOG_URI("fullUri: `%s`; fullUriWithAuth: `%s`", STR(fullUri), STR(fullUriWithAuth)); LOG_URI("username: `%s`; password: `%s`", STR(username), STR(password)); //4. Get the host:port pos = stringUri.find("/", cursor); if (pos == string::npos) { hostPort = stringUri.substr(cursor); cursor = stringUri.size() - 1; fullDocumentPathWithParameters = "/"; } else { hostPort = stringUri.substr(cursor, pos - cursor); cursor = pos + 1; fullDocumentPathWithParameters = "/" + stringUri.substr(cursor); } trim(hostPort); if (hostPort == "") { FATAL("Invalid host:port specified"); return false; } pos = hostPort.find(":"); if (pos == string::npos) { host = hostPort; portSpecified = false; } else { host = hostPort.substr(0, pos); trim(host); portString = hostPort.substr(pos + 1); portSpecified = true; port = (uint16_t) atoi(STR(portString)); if (format("%"PRIu16, port) != portString) { FATAL("Invalid port number specified: `%s`", STR(portString)); return false; } } LOG_URI("host: %s; port: %"PRIu16"; portSpecified: %d", STR(host), port, portSpecified); //5. fullDocumentPathWithParameters fullDocumentPath = "/"; fullParameters = ""; documentPath = "/"; document = ""; documentWithFullParameters = ""; parameters.Reset(); parameters.IsArray(false); if (fullDocumentPathWithParameters != "/") { pos = fullDocumentPathWithParameters.find("?"); if (pos == string::npos) { fullDocumentPath = fullDocumentPathWithParameters; fullParameters = ""; } else { fullDocumentPath = fullDocumentPathWithParameters.substr(0, pos); fullParameters = fullDocumentPathWithParameters.substr(pos + 1); } trim(fullParameters); if (fullParameters != "") { vector<string> elements; split(fullParameters, "&", elements); for (uint32_t i = 0; i < elements.size(); i++) { string kvp = elements[i]; if (kvp == "") continue; string k = ""; string v = ""; pos = kvp.find("="); if (pos == string::npos) { k = kvp; v = ""; } else { k = kvp.substr(0, pos); v = kvp.substr(pos + 1); } if (k == "") continue; parameters[k] = v; } } bool rtmpDocument = false; if (scheme.find("rtmp") == 0) { pos = fullDocumentPath.find(':'); if (pos == string::npos) { rtmpDocument = false; } else { pos = fullDocumentPath.rfind('/', pos); if (pos == string::npos) { rtmpDocument = false; } else { rtmpDocument = true; } } } else { rtmpDocument = false; } if (rtmpDocument) { pos = fullDocumentPath.find(':'); pos = fullDocumentPath.rfind('/', pos); documentPath = fullDocumentPath.substr(0, pos + 1); document = fullDocumentPath.substr(pos + 1); } else { for (string::size_type i = fullDocumentPath.size() - 1; i != 0; i--) { if (fullDocumentPath[i] == '/') break; document = fullDocumentPath[i] + document; } documentPath = fullDocumentPath.substr(0, fullDocumentPath.size() - document.size()); } documentWithFullParameters = document; if (fullParameters != "") documentWithFullParameters += "?" + fullParameters; } LOG_URI("fullDocumentPathWithParameters: `%s`", STR(fullDocumentPathWithParameters)); LOG_URI("fullDocumentPath: `%s`", STR(fullDocumentPath)); LOG_URI("fullParameters: `%s`", STR(fullParameters)); LOG_URI("documentPath: `%s`", STR(documentPath)); LOG_URI("document: `%s`", STR(document)); LOG_URI("documentWithFullParameters: `%s`", STR(documentWithFullParameters)); LOG_URI("parameters:"); #ifdef DEBUG_URI FOR_MAP(parameters, string, Variant, i) { LOG_URI("\t`%s`: `%s`", STR(MAP_KEY(i)), STR(MAP_VAL(i))); }
void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, int enc) { const unsigned char *true_key; if (iv == NULL) { LOGE("cipher_context_set_iv(): IV is null"); return; } if (!enc) { memcpy(ctx->iv, iv, iv_len); } if (enc_method >= SALSA20) { return; } if (enc_method == RC4_MD5 || enc_method == RC4_MD5_6) { unsigned char key_iv[32]; memcpy(key_iv, enc_key, 16); memcpy(key_iv + 16, iv, iv_len); true_key = enc_md5(key_iv, 16 + iv_len, NULL); iv_len = 0; } else { true_key = enc_key; } #ifdef USE_CRYPTO_APPLECC cipher_cc_t *cc = &ctx->cc; if (cc->valid == kCCContextValid) { memcpy(cc->iv, iv, iv_len); memcpy(cc->key, true_key, enc_key_len); cc->iv_len = iv_len; cc->key_len = enc_key_len; cc->encrypt = enc ? kCCEncrypt : kCCDecrypt; if (cc->cryptor != NULL) { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } CCCryptorStatus ret; ret = CCCryptorCreateWithMode( cc->encrypt, cc->mode, cc->cipher, cc->padding, cc->iv, cc->key, cc->key_len, NULL, 0, 0, 0, &cc->cryptor); if (ret != kCCSuccess) { if (cc->cryptor != NULL) { CCCryptorRelease(cc->cryptor); cc->cryptor = NULL; } FATAL("Cannot set CommonCrypto key and IV"); } return; } #endif cipher_evp_t *evp = &ctx->evp; if (evp == NULL) { LOGE("cipher_context_set_iv(): Cipher context is null"); return; } #if defined(USE_CRYPTO_OPENSSL) if (!EVP_CipherInit_ex(evp, NULL, NULL, true_key, iv, enc)) { EVP_CIPHER_CTX_cleanup(evp); FATAL("Cannot set key and IV"); } #elif defined(USE_CRYPTO_POLARSSL) // XXX: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead. if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher key"); } #if POLARSSL_VERSION_NUMBER >= 0x01030000 if (cipher_set_iv(evp, iv, iv_len) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher IV"); } if (cipher_reset(evp) != 0) { cipher_free_ctx(evp); FATAL("Cannot finalize PolarSSL cipher context"); } #else if (cipher_reset(evp, iv) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher IV"); } #endif #elif defined(USE_CRYPTO_MBEDTLS) if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot set mbed TLS cipher key"); } if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot set mbed TLS cipher IV"); } if (mbedtls_cipher_reset(evp) != 0) { mbedtls_cipher_free(evp); FATAL("Cannot finalize mbed TLS cipher context"); } #endif #ifdef DEBUG dump("IV", (char *)iv, iv_len); #endif }
bool TCPAcceptor::Accept() { sockaddr address; memset(&address, 0, sizeof (sockaddr)); socklen_t len = sizeof (sockaddr); int32_t fd; //1. Accept the connection fd = accept(_inboundFd, &address, &len); if ((fd < 0) || (!setFdCloseOnExec(fd))) { int err = errno; FATAL("Unable to accept client connection: (%d) %s", err, strerror(err)); return false; } if (!_enabled) { CLOSE_SOCKET(fd); _droppedCount++; WARN("Acceptor is not enabled. Client dropped: %s:%"PRIu16" -> %s:%"PRIu16, inet_ntoa(((sockaddr_in *) & address)->sin_addr), ENTOHS(((sockaddr_in *) & address)->sin_port), STR(_ipAddress), _port); return true; } if (!setFdOptions(fd, false)) { FATAL("Unable to set socket options"); CLOSE_SOCKET(fd); return false; } //4. Create the chain BaseProtocol *pProtocol = ProtocolFactoryManager::CreateProtocolChain( _protocolChain, _parameters); if (pProtocol == NULL) { FATAL("Unable to create protocol chain"); CLOSE_SOCKET(fd); return false; } //5. Create the carrier and bind it TCPCarrier *pTCPCarrier = new TCPCarrier(fd); pTCPCarrier->SetProtocol(pProtocol->GetFarEndpoint()); pProtocol->GetFarEndpoint()->SetIOHandler(pTCPCarrier); //6. Register the protocol stack with an application if (_pApplication != NULL) { pProtocol = pProtocol->GetNearEndpoint(); pProtocol->SetApplication(_pApplication); } if (pProtocol->GetNearEndpoint()->GetOutputBuffer() != NULL) pProtocol->GetNearEndpoint()->EnqueueForOutbound(); _acceptedCount++; INFO("Client connected: %s:%"PRIu16" -> %s:%"PRIu16, inet_ntoa(((sockaddr_in *) & address)->sin_addr), ENTOHS(((sockaddr_in *) & address)->sin_port), STR(pTCPCarrier->GetNearEndpointAddressIp()), pTCPCarrier->GetNearEndpointPort()); //7. Done return true; }
int main(int argc, char *argv[]) { const char *fs = NULL; setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */ cmdname = __progname; if (argc == 1) { fprintf(stderr, "usage: %s [-safe] [-V] [-d[n]] [-F fs] " "[-v var=value] [prog | -f progfile]\n\tfile ...\n", cmdname); exit(1); } signal(SIGFPE, fpecatch); yyin = NULL; symtab = makesymtab(NSYMTAB); while (argc > 1 && argv[1][0] == '-' && argv[1][1] != '\0') { if (strcmp(argv[1], "--") == 0) { /* explicit end of args */ argc--; argv++; break; } switch (argv[1][1]) { case 's': if (strcmp(argv[1], "-safe") == 0) safe = 1; break; case 'f': /* next argument is program filename */ if (argv[1][2] != 0) { /* arg is -fsomething */ if (npfile >= MAX_PFILE - 1) FATAL("too many -f options"); pfile[npfile++] = &argv[1][2]; } else { /* arg is -f something */ argc--; argv++; if (argc <= 1) FATAL("no program filename"); if (npfile >= MAX_PFILE - 1) FATAL("too many -f options"); pfile[npfile++] = argv[1]; } break; case 'F': /* set field separator */ if (argv[1][2] != 0) { /* arg is -Fsomething */ if (argv[1][2] == 't' && argv[1][3] == 0) /* wart: t=>\t */ fs = "\t"; else if (argv[1][2] != 0) fs = &argv[1][2]; } else { /* arg is -F something */ argc--; argv++; if (argc > 1 && argv[1][0] == 't' && argv[1][1] == 0) /* wart: t=>\t */ fs = "\t"; else if (argc > 1 && argv[1][0] != 0) fs = &argv[1][0]; } if (fs == NULL || *fs == '\0') WARNING("field separator FS is empty"); break; case 'v': /* -v a=1 to be done NOW. one -v for each */ if (argv[1][2] != 0) { /* arg is -vsomething */ if (isclvar(&argv[1][2])) setclvar(&argv[1][2]); else FATAL("invalid -v option argument: %s", &argv[1][2]); } else { /* arg is -v something */ argc--; argv++; if (argc <= 1) FATAL("no variable name"); if (isclvar(argv[1])) setclvar(argv[1]); else FATAL("invalid -v option argument: %s", argv[1]); } break; case 'd': dbg = atoi(&argv[1][2]); if (dbg == 0) dbg = 1; printf("awk %s\n", version); break; case 'V': /* added for exptools "standard" */ printf("awk %s\n", version); exit(0); break; default: WARNING("unknown option %s ignored", argv[1]); break; } argc--; argv++; } /* argv[1] is now the first argument */ if (npfile == 0) { /* no -f; first argument is program */ if (argc <= 1) { if (dbg) exit(0); FATAL("no program given"); } DPRINTF( ("program = |%s|\n", argv[1]) ); lexprog = argv[1]; argc--; argv++; } recinit(recsize); syminit(); compile_time = 1; argv[0] = cmdname; /* put prog name at front of arglist */ DPRINTF( ("argc=%d, argv[0]=%s\n", argc, argv[0]) ); arginit(argc, argv); if (!safe) envinit(environ); yyparse(); setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */ if (fs) *FS = qstring(fs, '\0'); DPRINTF( ("errorflag=%d\n", errorflag) ); if (errorflag == 0) { compile_time = 0; run(winner); } else bracecheck(); return(errorflag); }
static void server_resolve_cb(EV_P_ ev_timer *watcher, int revents) { int err; struct addrinfo *result, *rp; struct server_ctx *server_ctx = (struct server_ctx *) (((void*)watcher) - sizeof(ev_io)); struct server *server = server_ctx->server; asyncns_t *asyncns = server->listen_ctx->asyncns; asyncns_query_t *query = server->query; if (asyncns == NULL || query == NULL) { LOGE("invalid dns query."); close_and_free_server(EV_A_ server); return; } if (asyncns_wait(asyncns, 0) == -1) { // asyncns error FATAL("asyncns exit unexpectedly."); } if (!asyncns_isdone(asyncns, query)) { // wait for reolver return; } if (verbose) { LOGD("asyncns resolved."); } ev_timer_stop(EV_A_ watcher); err = asyncns_getaddrinfo_done(asyncns, query, &result); if (err) { ERROR("getaddrinfo"); close_and_free_server(EV_A_ server); } else { // Use IPV4 address if possible for (rp = result; rp != NULL; rp = rp->ai_next) { if (rp->ai_family == AF_INET) break; } if (rp == NULL) { rp = result; } struct remote *remote = connect_to_remote(rp, server->listen_ctx->iface); if (remote == NULL) { LOGE("connect error."); close_and_free_server(EV_A_ server); } else { server->remote = remote; remote->server = server; // XXX: should handel buffer carefully if (server->buf_len > 0) { memcpy(remote->buf, server->buf + server->buf_idx, server->buf_len); remote->buf_len = server->buf_len; remote->buf_idx = 0; server->buf_len = 0; server->buf_idx = 0; } // listen to remote connected event ev_io_start(EV_A_ &remote->send_ctx->io); } } // release addrinfo asyncns_freeaddrinfo(result); }
///////////////////////////////////////////////////////////////////////////// // Destructor: issue fatal error if still has observers ///////////////////////////////////////////////////////////////////////////// CResults::~CResults() { FATAL(!lObs.empty()); }
int idn_utf8_getwc(const char *s, size_t len, unsigned long *vp) { unsigned long v; unsigned long min; const unsigned char *p = (const unsigned char *)s; int c; int width; int rest; assert(s != NULL); #if 0 TRACE(("idn_utf8_getwc(s=<%s>,len=%d)\n", idn__debug_hexstring(s, 10), len)); #endif c = *p++; width = UTF8_WIDTH(c); switch (width) { case 0: return (0); case 1: v = c; min = 0; break; case 2: v = c & 0x1f; min = 0x80; break; case 3: v = c & 0xf; min = 0x800; break; case 4: v = c & 0x7; min = 0x10000; break; case 5: v = c & 3; min = 0x200000; break; case 6: v = c & 1; min = 0x4000000; break; default: FATAL(("idn_utf8_getint: internal error\n")); return (0); } if (len < width) return (0); rest = width - 1; while (rest-- > 0) { if (!VALID_CONT_BYTE(*p)) return (0); v = (v << 6) | (*p & 0x3f); p++; } if (v < min) return (0); *vp = v; return (width); }
void rom_init() { struct mmu *rom,*rom2; FILE *f; f = fopen(prefs.tosimage, "rb"); if(!f) { FATAL("Could not open TOS image file\n"); } fseek(f, 0, SEEK_END); ROMSIZE = ftell(f); rewind(f); switch(ROMSIZE) { case ROMSIZE_OLD: ROMBASE = ROMBASE_OLD; break; case ROMSIZE_NEW: ROMBASE = ROMBASE_NEW; break; default: FATAL("Unknown ROM image format"); } memory = xmalloc(sizeof(BYTE) * ROMSIZE); if(!memory) { return; } rom = mmu_create("ROM0", "ROM"); rom->start = ROMBASE; rom->size = ROMSIZE; rom->read_byte = rom_read_byte; rom->read_word = rom_read_word; rom->state_collect = rom_state_collect; rom->state_restore = rom_state_restore; rom->diagnostics = rom_diagnostics; mmu_register(rom); if(fread(memory, 1, ROMSIZE, f) != ROMSIZE) { FATAL("Error reading TOS image file"); } fclose(f); memory2 = xmalloc(sizeof(BYTE) * ROMSIZE2); if(!memory2) { return; } rom2 = mmu_create("ROM1", "First 8 bytes of memory"); memcpy(memory2, memory, ROMSIZE2); rom2->start = ROMBASE2; /* First 8 bytes of memory is ROM */ rom2->size = ROMSIZE2; rom2->read_byte = rom_read_byte; rom2->read_word = rom_read_word; rom2->state_collect = rom_state_collect; rom2->state_restore = rom_state_restore; rom2->diagnostics = rom_diagnostics; mmu_register(rom2); }
int main (int argc, char **argv) { int quit = 0; #if defined(__GLIBC__) setup_signal_handlers (); #endif /* command line/config options */ verify_global_config (argc, argv); parse_conf_file (&argc, &argv); parse_cmd_line (argc, argv); /* initialize storage */ init_storage (); /* setup to use the current locale */ set_locale (); #ifdef HAVE_LIBGEOIP init_geoip (); #endif /* init logger */ logger = init_log (); set_signal_data (logger); /* init parsing spinner */ parsing_spinner = new_gspinner (); parsing_spinner->processed = &logger->processed; /* outputting to stdout */ if (conf.output_html) { ui_spinner_create (parsing_spinner); goto out; } /* init curses */ set_input_opts (); if (conf.no_color || has_colors () == FALSE) { conf.color_scheme = NO_COLOR; conf.no_color = 1; } else { start_color (); } init_colors (0); init_windows (&header_win, &main_win); set_curses_spinner (parsing_spinner); /* configuration dialog */ if (isatty (STDIN_FILENO) && (conf.log_format == NULL || conf.load_conf_dlg)) { refresh (); quit = render_confdlg (logger, parsing_spinner); } /* straight parsing */ else { ui_spinner_create (parsing_spinner); } out: /* main processing event */ time (&start_proc); if (conf.load_from_disk) set_general_stats (); if (!quit && parse_log (&logger, NULL, -1)) FATAL ("Error while processing file"); logger->offset = logger->processed; /* If parser.c, process_log() did not parse any lines from the * provided dataset, then display a message that no valid entries * were parsed. * * If it gets to this point, usually the log/date/time format did * not match the log entries. */ if (logger->valid == 0) FATAL ("Nothing valid to process. Verify your date/time/log format."); /* init reverse lookup thread */ gdns_init (); parse_initial_sort (); allocate_holder (); end_spinner (); time (&end_proc); /* stdout */ if (conf.output_html) standard_output (); /* curses */ else curses_output (); /* clean */ house_keeping (); return EXIT_SUCCESS; }
bool InboundHTTP4RTMP::SignalInputData(IOBuffer &buffer) { //1. Get the HTTP far protool and test to see if it has ContentLength InboundHTTPProtocol *pHTTP = (InboundHTTPProtocol *) _pFarProtocol; if (pHTTP == NULL || pHTTP->GetContentLength() == 0) { FATAL("Invalid HTTP request"); return false; } //2. Test it and see if all the data was transfered if (!pHTTP->TransferCompleted()) { return true; } //3. Get the HTTP request Variant request = pHTTP->GetHeaders(); //4. Is this a keep-alive? pHTTP->SetDisconnectAfterTransfer( request[HTTP_HEADERS][HTTP_HEADERS_CONNECTION] != HTTP_HEADERS_CONNECTION_KEEP_ALIVE); DeleteNearProtocol(false); //4. Get the URL string url = request[HTTP_FIRST_LINE][HTTP_URL]; //5. split it in meaningful parts vector<string> parts; split(url, "/", parts); if (parts.size() < 2) { FATAL("Invalid request:\n%s", STR(request.ToString())); return false; } //7. Do the dammage bool result; if (parts[1] == "fcs") { result = ProcessFcs(parts); buffer.Ignore(pHTTP->GetContentLength()); } else if (parts[1] == "open") { result = ProcessOpen(parts); buffer.Ignore(pHTTP->GetContentLength()); } else if (parts[1] == "idle") { result = ProcessIdle(parts); buffer.Ignore(pHTTP->GetContentLength()); } else if (parts[1] == "send") { if (GETAVAILABLEBYTESCOUNT(buffer) < 1) return false; _inputBuffer.ReadFromBuffer(GETIBPOINTER(buffer), pHTTP->GetContentLength()); buffer.Ignore(pHTTP->GetContentLength()); result = ProcessSend(parts); } else { FATAL("Invalid command: %s", STR(parts[1])); result = false; } //8. Cleanup if (!result) { DeleteNearProtocol(true); EnqueueForDelete(); } //9. Done return result; }