void initServer(char *host, int port) { char *msg; int listendfd = anetTcpServer(msg, port, host); if (listendfd <= 0) { lookup_log(LOG_DEBUG, "create server error %s\n", msg); exit(0); } lookup_log(LOG_DEBUG, "listened %s:%d\n", host, port); if (anetNonBlock(msg, listendfd) < 0) { lookup_log(LOG_DEBUG, "set noblocking server error %s\n", msg); exit(0); } pool = create_event(1024); add_event(pool, listendfd, EPOLLIN, serverAccept); while (1) { lookup_log(LOG_DEBUG, "polling\n"); int num = handle_event(pool, 30); int i; for (i=0; i<num; i++) { int fd = pool->epollEv[i].data.fd; noti_chain_callback cb = pool->events[fd].cb; (*cb) (&pool->events[fd], fd); } } close(listendfd); }
int serverWrite(event *ev, int fd) { lookup_log(LOG_DEBUG, "write\n"); int write = 0; if (ev->wr_pos == 0) { ev->body_data = build_request_str(ev->data); } write = anetWrite(fd, ev->body_data, ev->data->body_len + PROTOCOL_HAEDER_SIZE); if (write == 0 && errno == ECONNRESET) { lookup_log(LOG_DEBUG, "client close conn\n"); } ev->wr_pos == 0; if (del_event(pool, fd) < 0) { printf("%s\n", strerror(errno)); exit(0); } // dump_request(ev->data); int tmp = 0; int i = 0; while (tmp < ev->data->body_len) { lookup_log(LOG_DEBUG, "free:%s\n", ev->data->body[i].data); zfree(ev->data->body[i].data); tmp += ev->data->body[i].len + 3; zfree(ev->data->body[i]); i++; } close(fd); zfree(ev->data); zfree(ev->body_data); lookup_log(LOG_DEBUG, "close fd\n"); return 0; }
int serverRead(event *ev, int fd) { lookup_log(LOG_DEBUG, "read\n"); int read = 0; char buf[IO_PACKET_SIZE]; if (ev->wr_pos == 0) { read = anetRead(fd, &buf[0], PROTOCOL_HAEDER_SIZE); if (read == 0 && errno == ECONNRESET) { free_conn: ev->wr_pos = 0; del_event(pool, fd); close(fd); zfree(ev->data); lookup_log(LOG_DEBUG, "close fd\n"); return 0; } ev->data = parse_protocol_header(buf); } else { int block = (ev->data->body_len + PROTOCOL_HAEDER_SIZE - ev->wr_pos) / IO_PACKET_SIZE; if (block > 0) { read = anetRead(fd, &buf[0], IO_PACKET_SIZE); } else { read = anetRead(fd, &buf[0], (ev->data->body_len + PROTOCOL_HAEDER_SIZE - ev->wr_pos) % IO_PACKET_SIZE); } if (read == 0 && errno == ECONNRESET) { goto free_conn; } if (ev->body_data == NULL) { ev->body_data_size = IO_PACKET_SIZE * 2; ev->body_data = (char *)zmalloc(ev->body_data_size); memcpy(ev->body_data + ev->body_data_wr_pos, buf, read); ev->body_data_wr_pos += read; } else { if ((ev->body_data_wr_pos + read) > ev->body_data_size) { //resize ev->body_data_size = ev->body_data_size * 2; ev->body_data = (char *)zrealloc(ev->body_data, ev->body_data_size); } memcpy(ev->body_data + ev->body_data_wr_pos, buf, read); ev->body_data_wr_pos += read; } } if (read > 0) { ev->wr_pos += read; } lookup_log(LOG_DEBUG, "pos:%d\n", ev->wr_pos); if (ev->wr_pos >= (ev->data->body_len + PROTOCOL_HAEDER_SIZE)) { parse_protocol_body(ev->body_data, ev->data); ev->wr_pos = 0; processRequest((lookup_protocol *)ev->data); ev->cb = serverWrite; set_event(pool, fd, EPOLLOUT); } return 0; }
// rho0,u,H,T have independent lookups for mapping to i,j,k,l and already done in eos_lookup_degen() // u here stands for utotdiff,ptotdiff,and chidiff depending upon whichindep // here only need to look up jeos associated with u // notice that qarray and vartypearraylocal start at 1 not 0 static void eos_lookup_degen(int begin, int end, int skip, int whichtable, int whichindep, int *vartypearraylocal, FTYPE *qarray, FTYPEEOS *indexarray) { int qi; // is this expensive? // log_base(R-R0) // avoid nan's by choosing minimal density // old simple log10 way: // i = (x - x0)*[(N-1)/(x1-x0)] such that if x=x0, then i=0, if x=x1, then i=N-1 // new generalized log way: // i = (log_base(R-R0) - x_in)/dx for(qi=begin;qi<=end;qi++){ if(qi==skip) continue; if(qi==YEINDEP && whichyelooptype[whichtable]==YELOOPTYPESPECIAL){ lookup_yespecial(whichtable,vartypearraylocal[qi],qarray[qi],&indexarray[qi]); } else{ lookup_log(whichtable,vartypearraylocal[qi],qarray[qi],&indexarray[qi]); } // DEBUG: // dualfprintf(fail_file,"whichtable=%d qi=%d var=%d q=%21.15g index=%21.15g\n",whichtable,qi,vartypearraylocal[qi],qarray[qi],indexarray[qi]); } }
int addLookupEntry(char *key, char *value, unsigned char type) { lookupKey *lookKey = zmalloc(sizeof(lookupKey)); lookKey->name = strdup(key); lookKey->type = type; lookup_log(LOG_DEBUG, "table add %s,%d\n", key, type); dictAdd(dt, (void *)lookKey, (void *)value); return 0; }
char* findLookupVal(char *key, unsigned char type) { lookup_log(LOG_DEBUG, "table find %s,%d\n", key, type); lookupKey find; find.name = key; find.type = type; char *val = (char *)dictFetchValue(dt, &find); return val; }
int serverAccept(event *v, int fd) { char *msg; char clientHost[32]; int clientPort, clientFd; if ((clientFd = anetTcpAccept(msg, fd, &clientHost[0], &clientPort)) > 0) { lookup_log(LOG_DEBUG, "accept %s:%d fd:%d\n", clientHost, clientPort, clientFd); if (anetNonBlock(msg, clientFd) < 0) { return -1; } add_event(pool, clientFd, EPOLLIN, serverRead); } return 0; }
/** Create a new SSL slave. * \param port The port to listen on for SSL connections. * \return 0 on success, -1 on failure */ int make_ssl_slave(void) { int fds[2]; if (ssl_slave_state != SSL_SLAVE_DOWN) { do_rawlog(LT_ERR, "Attempt to start ssl slave when a copy is already running."); return -1; } if (ssl_slave_halted) { do_rawlog(LT_ERR, "Attempt to start disabled ssl slave."); return -1; } if (startup_attempts == 0) time(&startup_window); startup_attempts += 1; if (startup_attempts > MAX_ATTEMPTS) { time_t now; time(&now); if (difftime(now, startup_window) <= 60.0) { do_rawlog(LT_ERR, "Disabling ssl_slave due to too many errors."); ssl_slave_halted = true; return -1; } else { /* Reset counter */ startup_window = now; startup_attempts = 0; } } if (pipe(fds) < 0) { do_rawlog(LT_ERR, "Unable to create pipe to speak to ssl_slave: %s", strerror(errno)); return -1; } if (fds[0] >= maxd) maxd = fds[0] + 1; if (fds[1] >= maxd) maxd = fds[1] + 1; if ((ssl_slave_pid = fork()) == 0) { /* Set up and exec ssl_slave */ int n, errfd = -1, connfd = -1; struct log_stream *lg; /* Close all open files but LT_CONN and LT_ERR, and assign them as stdout and stderr, respectively. */ /* If called on startup, maxd is 0 but log files and such have been opened. Use a reasonable max descriptor. If called because ssl_slave went down, maxd will be set properly already. */ if (!maxd) maxd = 20; lg = lookup_log(LT_ERR); if (lg) errfd = fileno(lg->fp); lg = lookup_log(LT_CONN); if (lg) connfd = fileno(lg->fp); dup2(fds[0], 0); /* stdin */ dup2(connfd, 1); /* stdout */ dup2(errfd, 2); /* stderr */ for (n = 3; n < maxd; n++) close(n); execl("./ssl_slave", "ssl_slave", "for", MUDNAME, NULL); penn_perror("execing ssl slave"); return EXIT_FAILURE; } else if (ssl_slave_pid < 0) { do_rawlog(LT_ERR, "Failure to fork ssl_slave: %s", strerror(errno)); return -1; } else { struct ssl_slave_config cf; ssl_slave_ctl_fd = fds[1]; close(fds[0]); /* Set up arguments to the slave */ memset(&cf, 0, sizeof cf); strcpy(cf.socket_file, options.socket_file); strcpy(cf.ssl_ip_addr, SSL_IP_ADDR); cf.normal_port = options.port; cf.ssl_port = options.ssl_port; strcpy(cf.private_key_file, options.ssl_private_key_file); strcpy(cf.ca_file, options.ssl_ca_file); cf.require_client_cert = options.ssl_require_client_cert; cf.keepalive_timeout = options.keepalive_timeout; if (write(ssl_slave_ctl_fd, &cf, sizeof cf) < 0) { do_rawlog(LT_ERR, "Unable to send ssl_slave config options: %s", strerror(errno)); return -1; } ssl_slave_state = SSL_SLAVE_RUNNING; do_rawlog(LT_ERR, "Spawning ssl_slave, communicating over %s, pid %d.", options.socket_file, ssl_slave_pid); return 0; } return -1; }