static int nc_save_argv(int argc, char *const *argv) { size_t len; int i; nc_os_argv = (char **) argv; nc_argc = argc; nc_argv = malloc((argc + 1) * sizeof(char *)); if (nc_argv == NULL) { return NC_ERROR; } for (i = 0; i < argc; i++) { len = nc_strlen(argv[i]) + 1; nc_argv[i] = malloc(len); if (nc_argv[i] == NULL) { return NC_ERROR; } (void) nc_cpystrn((u_char *) nc_argv[i], (u_char *) argv[i], len); } nc_argv[i] = NULL; //nc_os_environ = environ; return NC_OK; }
struct server* ffi_server_new(struct server_pool *pool, char *name, char *id, char *ip, int port) { struct server *s; struct string address; rstatus_t status; s = nc_alloc(sizeof(struct server)); if (s == NULL) { log_error("failed to allocate memory"); return NULL; } s->owner = pool; s->idx = 0; s->weight = 1; /* set name */ string_init(&s->name); string_copy(&s->name, (uint8_t*)name, (uint32_t)nc_strlen(name)); string_init(&s->pname); string_copy(&s->pname, (uint8_t*)name, (uint32_t)nc_strlen(name)); string_init(&address); string_copy(&address, (uint8_t*)ip, (uint32_t)nc_strlen(ip)); /* set port */ s->port = (uint16_t)port; status = nc_resolve(&address, s->port, &s->sockinfo); if (status != NC_OK) { log_error("conf: failed to resolve %.*s:%d", address.len, address.data, s->port); return NULL; } s->family = s->sockinfo.family; s->addrlen = s->sockinfo.addrlen; s->addr = (struct sockaddr *)&s->sockinfo.addr; s->ns_conn_q = 0; TAILQ_INIT(&s->s_conn_q); s->next_retry = 0LL; s->failure_count = 0; return s; }
int _ssl_init(nsp_state *N, TCP_SOCKET *sock, short srvmode, char *certfile, char *keyfile) { #define __FN__ __FILE__ ":_ssl_init()" #if defined HAVE_OPENSSL SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); if (srvmode) { sock->ssl_meth = (SSL_METHOD *)SSLv23_server_method(); } else { sock->ssl_meth = (SSL_METHOD *)SSLv23_client_method(); } sock->ssl_ctx = SSL_CTX_new(sock->ssl_meth); if (!sock->ssl_ctx) { n_warn(N, __FN__, "SSL Error"); return -1; } if ((certfile == NULL) || (keyfile == NULL)) return 0; if (SSL_CTX_use_certificate_file(sock->ssl_ctx, certfile, SSL_FILETYPE_PEM) <= 0) { n_warn(N, __FN__, "SSL Error loading certificate '%s'", certfile); return -1; } if (SSL_CTX_use_PrivateKey_file(sock->ssl_ctx, keyfile, SSL_FILETYPE_PEM) <= 0) { n_warn(N, __FN__, "SSL Error loading private key '%s'", keyfile); return -1; } if (!SSL_CTX_check_private_key(sock->ssl_ctx)) { n_warn(N, __FN__, "Private key does not match the public certificate"); return -1; } return 0; #elif defined HAVE_MBEDTLS const char *pers = "ssl_server"; int rc; mbedtls_ssl_config_init(&sock->conf); if ((rc = mbedtls_ssl_config_defaults(&sock->conf, srvmode ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { n_warn(N, __FN__, "mbedtls_ssl_config_defaults failed. error %d", rc); return -1; } mbedtls_ssl_conf_authmode(&sock->conf, MBEDTLS_SSL_VERIFY_NONE); mbedtls_entropy_init(&sock->entropy); mbedtls_ctr_drbg_init(&sock->ctr_drbg); if ((rc = mbedtls_ctr_drbg_seed(&sock->ctr_drbg, mbedtls_entropy_func, &sock->entropy, (const unsigned char *)pers, nc_strlen(pers))) != 0) { print_mbedtls_error(N, __FN__, rc); return -1; } mbedtls_ssl_conf_rng(&sock->conf, mbedtls_ctr_drbg_random, &sock->ctr_drbg); if ((certfile == NULL) || (keyfile == NULL)) { return 0; //if ((rc = mbedtls_x509_crt_parse(&sock->srvcert, (unsigned char *)mbedtls_test_srv_crt, nc_strlen(mbedtls_test_srv_crt))) != 0) { // print_mbedtls_error(N, __FN__, rc); // return -1; //} //if ((rc = mbedtls_x509_crt_parse(&sock->srvcert, (unsigned char *)mbedtls_test_ca_crt, nc_strlen(mbedtls_test_ca_crt))) != 0) { // print_mbedtls_error(N, __FN__, rc); // return -1; //} //if ((rc = mbedtls_pk_parse_key(&sock->pubkey, (unsigned char *)mbedtls_test_srv_key, nc_strlen(mbedtls_test_srv_key), NULL, 0)) != 0) { // print_mbedtls_error(N, __FN__, rc); // return -1; //} } else { if ((rc = mbedtls_x509_crt_parse_file(&sock->srvcert, certfile)) != 0) { //n_warn(N, __FN__, "x509_read_crtfile returned %08x", rc); print_mbedtls_error(N, __FN__, rc); return -1; } if ((rc = mbedtls_pk_parse_keyfile(&sock->pubkey, keyfile, NULL)) != 0) { //n_warn(N, __FN__, "x509_read_keyfile returned %08x", rc); print_mbedtls_error(N, __FN__, rc); return -1; } } mbedtls_ssl_conf_ca_chain(&sock->conf, sock->srvcert.next, NULL); if ((rc = mbedtls_ssl_conf_own_cert(&sock->conf, &sock->srvcert, &sock->pubkey)) != 0) { n_warn(N, __FN__, "mbedtls_ssl_conf_own_cert returned %08x", rc); return -1; } return 0; #endif #undef __FN__ }
struct server * sentinel_init(uint16_t sentinel_port, char *sentinel_ip) { rstatus_t status; struct server *sentinel; struct string address; struct sockinfo info; char pname[NC_PNAME_MAXLEN]; string_init(&address); sentinel_status = SENTINEL_CONN_DISCONNECTED; sentinel = (struct server *)nc_alloc(sizeof(*sentinel)); if(sentinel == NULL) { goto error; } /* sentinel server don't have owner server pool */ sentinel->owner = NULL; sentinel->ns_conn_q = 0; TAILQ_INIT(&sentinel->s_conn_q); sentinel->addr = NULL; string_init(&sentinel->pname); string_init(&sentinel->name); nc_snprintf(pname, NC_PNAME_MAXLEN, "%s:%d:0", sentinel_ip, sentinel_port); status = string_copy(&sentinel->pname, pname, (uint32_t)(nc_strlen(pname))); if (status != NC_OK) { goto error; } string_copy(&sentinel->name, pname, (uint32_t)(nc_strlen(pname)) - 2); if (status != NC_OK) { goto error; } sentinel->port = sentinel_port; status = string_copy(&address, sentinel_ip, (uint32_t)(nc_strlen(sentinel_ip))); if (status != NC_OK) { goto error; } status = nc_resolve(&address, sentinel_port, &info); if (status != NC_OK) { goto error; } sentinel->family = info.family; sentinel->addrlen = info.addrlen; sentinel->addr = (struct sockaddr*)nc_alloc(info.addrlen); if (sentinel->addr == NULL) { goto error; } nc_memcpy(sentinel->addr, &info.addr, info.addrlen); done: string_deinit(&address); return sentinel; error: sentinel_deinit(sentinel); sentinel = NULL; goto done; }
static rstatus_t stats_master_send_rsp(int *psd) { int n; ssize_t len; int sd; int i; nc_channel_msg_t message; char buf[1000]; memset(buf, 0, sizeof(char)*1000); char *snd_buf = NULL; memset(&message, 0, sizeof(nc_channel_msg_t)); message.command = NC_CMD_GET_STATS; if (*psd) { sd = accept(*psd, NULL, NULL); if (sd < 0) { log_error("accept on m %d failed: %s", sd, strerror(errno)); return NC_ERROR; } } // still in reconfiguration process if (nc_reload_start) { sprintf(buf, "%s", "no stats get due to still during reconfiguration period."); if (*psd) { len = nc_strlen(buf)+1; len = nc_sendn(sd, buf, len); if (len < 0) { log_error("send stats on sd %d failed: %s", sd, strerror(errno)); } close(sd); } return NC_OK; } //broadcast for (i = 0; i < nc_last_process; i++) { if (nc_processes[i].pid == -1 || nc_processes[i].pid == 0) { continue; } if (nc_write_channel(nc_processes[i].channel[0], &message, sizeof(nc_channel_msg_t)) == NC_OK) { if (nc_set_blocking(nc_processes[i].channel[0]) < 0) { log_error("set channel %d block failed while core timeout %s", nc_processes[i].channel[0] , strerror(errno)); continue; } n = nc_read_channel(nc_processes[i].channel[0], &env_global.ctrl_msg, sizeof(nc_channel_msg_t)); if (env_global.ctrl_msg.command != NC_CMD_GET_STATS || n < 0) { log_error("failure: get stats from worker %d receive length, %s", nc_processes[i].channel[0] , strerror(errno)); } else { log_error("success: get stats from worker %d receive length, %d", nc_processes[i].channel[0] , n); snd_buf = nc_alloc(n + n); len = nc_recvn(nc_processes[i].channel[0], snd_buf, n); if (len < 0) { if (*psd) { log_error("recv stats on sd %d failed: %s", sd, strerror(errno)); } nc_free(snd_buf); snd_buf = NULL; continue; } if (*psd) { len = nc_sendn(sd, snd_buf, len); if (len < 0) { log_error("send stats on sd %d failed: %s", sd, strerror(errno)); nc_free(snd_buf); snd_buf = NULL; continue; } } len = nc_write(env_global.stats_fd, snd_buf, len); if (len < 0) { log_error("nc_write %d failed: %s", env_global.stats_fd, strerror(errno)); continue; } nc_free(snd_buf); snd_buf = NULL; } if (nc_set_nonblocking(nc_processes[i].channel[0]) < 0) { log_error("set channel %d nonblock failed while core timeout %s", nc_processes[i].channel[0] , strerror(errno)); } } } if (*psd) { shutdown(sd, SHUT_RDWR); close(sd); } return NC_OK; }
static rstatus_t nc_get_options(int argc, char **argv, struct env_master *env) { int c, value; int len; int cores; opterr = 0; //ASSERT(0); for (;;) { c = getopt_long(argc, argv, short_options, long_options, NULL); if (c == -1) { /* no more options */ break; } switch (c) { case 'h': show_version = 1; show_help = 1; break; case 'V': show_version = 1; break; case 't': test_conf = 1; break; case 'd': daemonize = 1; break; case 'D': describe_stats = 1; show_version = 1; break; case 'v': value = nc_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("nutcracker: option -v requires a number"); return NC_ERROR; } env->log_level = value; break; case 'o': env->log_filename = optarg; len = nc_strlen(optarg) + 1; log_filename_global = malloc(len); if (log_filename_global == NULL) { return NC_ERROR; } nc_cpystrn((u_char *) log_filename_global, (u_char *) optarg, len); break; case 'c': env->conf_filename = optarg; len = nc_strlen(optarg) + 1; conf_filename_global = malloc(len); if (conf_filename_global == NULL) { return NC_ERROR; } nc_cpystrn((u_char *) conf_filename_global, (u_char *) optarg, len); break; case 's': value = nc_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("nutcracker: option -s requires a number"); return NC_ERROR; } if (!nc_valid_port(value)) { log_stderr("nutcracker: option -s value %d is not a valid " "port", value); return NC_ERROR; } env->stats_port = (uint16_t)value; break; case 'i': value = nc_atoi(optarg, strlen(optarg)); if (value < 0) { log_stderr("nutcracker: option -i requires a number"); return NC_ERROR; } env->stats_interval = value; break; case 'a': env->stats_addr = optarg; break; case 'p': env->pid_filename = optarg; break; case 'm': value = nc_atoi(optarg, strlen(optarg)); if (value <= 0) { log_stderr("nutcracker: option -m requires a non-zero number"); return NC_ERROR; } if (value < NC_MBUF_MIN_SIZE || value > NC_MBUF_MAX_SIZE) { log_stderr("nutcracker: mbuf chunk size must be between %zu and" \ " %zu bytes", NC_MBUF_MIN_SIZE, NC_MBUF_MAX_SIZE); return NC_ERROR; } env->mbuf_chunk_size = (size_t)value; break; case 'n': value = nc_atoi(optarg, strlen(optarg)); if (value <= 0) { log_stderr("nutcracker: option -n requires a non-zero number"); return NC_ERROR; } cores = sysconf(_SC_NPROCESSORS_ONLN); if (value > cores || value < 1) { log_stderr("bilitw: bilitw worker process number should be between %d and" \ " %d", 1, cores); return NC_ERROR; } env->worker_processes= value; break; case 'M': value = nc_atoi(optarg, strlen(optarg)); if (value <= 0) { log_stderr("nutcracker: option -M requires a non-zero number"); return NC_ERROR; } cores = sysconf(_SC_NPROCESSORS_ONLN); cores = (1<<cores) -1; if (value > cores || value < 1) { log_stderr("bilitw: bilitw worker process cpu mask should be set between %d and" \ " %d", 1, cores); return NC_ERROR; } env->cpu_mask = value; break; case '?': switch (optopt) { case 'o': case 'c': case 'p': log_stderr("nutcracker: option -%c requires a file name", optopt); break; case 'm': case 'v': case 's': case 'i': case 'n': case 'M': log_stderr("nutcracker: option -%c requires a number", optopt); break; case 'a': log_stderr("nutcracker: option -%c requires a string", optopt); break; default: log_stderr("nutcracker: invalid option -- '%c'", optopt); break; } return NC_ERROR; default: log_stderr("nutcracker: invalid option -- '%c'", optopt); return NC_ERROR; } } return NC_OK; }
uchar *n_decompose(nsp_state *N, char *srcfile, uchar *srctext, uchar **dsttext, int *dstsize) { #define __FN__ __FILE__ ":n_decompose()" cstate state; obj_t *cobj, *tobj; unsigned short op; uchar *p, *p2; settrace(); *dsttext = NULL; *dstsize = 0; if ((srctext[0] == 0x0D) && ((srctext[1] == 0xAC))) { n_warn(N, __FN__, "already chewed on this"); return srctext; } nc_memset((char *)&state, 0, sizeof(state)); state.lineno = 1; state.destmax = 1024; state.destbuf = (uchar *)n_alloc(N, state.destmax, 0); N->readptr = srctext; tobj = nsp_settable(N, &N->g, "decomped_script"); nsp_freetable(N, tobj); state.tobj1 = nsp_settable(N, tobj, "code"); n_decompose_sub(N, &state); /* header - 8 bytes */ testgrow(8); /* safe portable use of sprintf is still considered dangerous according to openbsd */ state.destbuf[state.offset++] = 0x0D; state.destbuf[state.offset++] = 0xAC; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; /* file size - 4 bytes */ state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; /* optab offset - 4 bytes (little endian) */ state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; /* symtab offset - 4 bytes (little endian) */ state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; state.destbuf[state.offset++] = 0; /* now write the ops */ /* optab offset */ writei4(state.offset, (state.destbuf + 12)); /* set line number to 1 */ testgrow((long)(5)); state.destbuf[state.offset++] = OP_LINENUM; writei4(1, (state.destbuf + state.offset)); state.offset += 4; for (cobj = state.tobj1->val->d.table.f; cobj; cobj = cobj->next) { op = (unsigned short)cobj->val->attr; cobj->val->attr = 0; if (op == OP_LINENUM) { testgrow((long)(5)); state.destbuf[state.offset++] = op & 255; writei4((int)cobj->val->d.num, (state.destbuf + state.offset)); state.offset += 4; continue; } if (!nsp_isstr(cobj)) break; if (op == OP_UNDEFINED) break; if (op == OP_POBRACE) { testgrow((long)(5)); state.destbuf[state.offset++] = op & 255; writei4(0, (state.destbuf + state.offset)); state.offset += 4; continue; } else if (op == OP_POPAREN) { testgrow((long)(3)); state.destbuf[state.offset++] = op & 255; writei2(0, (state.destbuf + state.offset)); state.offset += 2; continue; } else if (op == OP_STRDATA || op == OP_ESTRDATA) { testgrow((long)(6 + cobj->val->size)); state.destbuf[state.offset++] = op & 255; writei4(cobj->val->size, (state.destbuf + state.offset)); state.offset += 4; nc_memcpy((char *)state.destbuf + state.offset, cobj->val->d.str, cobj->val->size); state.offset += cobj->val->size; state.destbuf[state.offset++] = 0; } else if (op == OP_NUMDATA) { testgrow((long)(3 + cobj->val->size)); state.destbuf[state.offset++] = op & 255; state.destbuf[state.offset++] = (uchar)(cobj->val->size & 255); nc_memcpy((char *)state.destbuf + state.offset, cobj->val->d.str, cobj->val->size); state.offset += cobj->val->size; state.destbuf[state.offset++] = 0; } else if (op == OP_LABEL) { testgrow((long)(3 + cobj->val->size)); state.destbuf[state.offset++] = op & 255; state.destbuf[state.offset++] = (uchar)(cobj->val->size & 255); nc_memcpy((char *)state.destbuf + state.offset, cobj->val->d.str, cobj->val->size); state.offset += cobj->val->size; state.destbuf[state.offset++] = '\0'; } else if (OP_ISMATH(op) || OP_ISKEY(op) || OP_ISPUNC(op)) { testgrow(1); state.destbuf[state.offset++] = op & 255; if (op == OP_KFUNC) { char *p = srcfile; //n_warn(N, __FN__, "'%s'", p); if (cobj->next->val->attr == OP_LABEL) { cobj = cobj->next; op = (unsigned short)cobj->val->attr; cobj->val->attr = 0; testgrow((long)(3 + cobj->val->size)); state.destbuf[state.offset++] = op & 255; state.destbuf[state.offset++] = (uchar)(cobj->val->size & 255); nc_memcpy((char *)state.destbuf + state.offset, cobj->val->d.str, cobj->val->size); state.offset += cobj->val->size; state.destbuf[state.offset++] = '\0'; } if (srcfile == NULL) p = ""; testgrow((long)(3 + nc_strlen(p))); state.destbuf[state.offset++] = OP_LABEL; state.destbuf[state.offset++] = (uchar)(nc_strlen(p) & 255); nc_memcpy((char *)state.destbuf + state.offset, p, nc_strlen(p)); state.offset += nc_strlen(p); state.destbuf[state.offset++] = '\0'; } } else { n_warn(N, __FN__, "bad op?"); } } /* file size */ writei4(state.offset, (state.destbuf + 8)); /* add some trailing nulls for fun... */ testgrow(4); writei4(0, (state.destbuf + state.offset)); state.offset += 4; /* n_dumpvars(N, &N->g, 0); */ nsp_freetable(N, tobj); *dsttext = state.destbuf; *dstsize = state.destmax; for (p = *dsttext + 12; p < *dsttext + state.offset - 4;) { if (*p == OP_LINENUM) { p += 5; continue; } if (*p == OP_POBRACE) { p2 = n_seekop(N, p, 1); if (p2 <= p) { n_warn(N, __FN__, "pointer did not progress"); break; } --p2; // if (*p2!=OP_PCBRACE) n_warn(N, __FN__, "no OP_PCBRACE? %d", (p+(p2-p)+5)[0]); if (*p2 != OP_PCBRACE) { /* int i; for (i=0;i<state.offset;i++) { if (i==p2-*dsttext) { printf("-----------------------\r\n[%d]\r\n-------------------", state.destbuf[i]); } else { if (state.destbuf[i]>=32 && state.destbuf[i]<128) { printf("'%c' %d\r\n", state.destbuf[i], state.destbuf[i]); } else { printf("%d\r\n", state.destbuf[i]); } } } */ n_warn(N, __FN__, "no OP_PCBRACE? %d .. %d %d %d %d [%d] %d %d", OP_PCBRACE, p2[-4], p2[-3], p2[-2], p2[-1], p2[0], p2[1], p2[2]); //n_decompile(N, *dsttext+12, *dsttext+state.offset-4, NULL, 0); } writei4((p2 - p - 5), (p + 1)); } else if (*p == OP_POPAREN) { p2 = n_seekop(N, p, 1); if (p2 <= p) { n_warn(N, __FN__, "pointer did not progress"); break; } --p2; if (*p2 != OP_PCPAREN) { n_warn(N, __FN__, "no OP_PCPAREN? %d .. %d %d %d %d [%d] %d %d", OP_PCPAREN, p2[-4], p2[-3], p2[-2], p2[-1], p2[0], p2[1], p2[2]); } writei2((p2 - p - 3), (p + 1)); } p = n_seekop(N, p, 0); } return *dsttext; #undef __FN__ }