//拷贝conf_server数组中的相关内容到server_pool->server中 rstatus_t conf_server_each_transform(void *elem, void *data) { struct conf_server *cs = elem; struct array *server = data; struct server *s; ASSERT(cs->valid); s = array_push(server); ASSERT(s != NULL); s->idx = array_idx(server, s); s->owner = NULL; s->pname = cs->pname; s->name = cs->name; s->addrstr = cs->addrstr; s->port = (uint16_t)cs->port; s->weight = (uint32_t)cs->weight; nc_memcpy(&s->info, &cs->info, sizeof(cs->info)); s->ns_conn_q = 0; TAILQ_INIT(&s->s_conn_q); s->next_retry = 0LL; s->failure_count = 0; log_debug(LOG_VERB, "transform to server %"PRIu32" '%.*s'", s->idx, s->pname.len, s->pname.data); return NC_OK; }
static int nc_resolve_inet(struct string *name, int port, struct sockinfo *si) { int status; struct addrinfo *ai, *cai; /* head and current addrinfo */ struct addrinfo hints; char *node, service[NC_UINTMAX_MAXLEN]; bool found; ASSERT(nc_valid_port(port)); memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_NUMERICSERV; //ai_numericserv hints.ai_family = AF_UNSPEC; /* AF_INET or AF_INET6 */ hints.ai_socktype = SOCK_STREAM; //sock_stream hints.ai_protocol = 0; hints.ai_addrlen = 0; hints.ai_addr = NULL; hints.ai_canonname = NULL; if (name != NULL) { node = (char *)name->data; } else { /* * If AI_PASSIVE flag is specified in hints.ai_flags, and node is * NULL, then the returned socket addresses will be suitable for * bind(2)ing a socket that will accept(2) connections. The returned * socket address will contain the wildcard IP address. */ node = NULL; hints.ai_flags |= AI_PASSIVE; } nc_snprintf(service, NC_UINTMAX_MAXLEN, "%d", port); status = getaddrinfo(node, service, &hints, &ai); if (status < 0) { log_error("address resolution of node '%s' service '%s' failed: %s", node, service, gai_strerror(status)); return -1; } /* * getaddrinfo() can return a linked list of more than one addrinfo, * since we requested for both AF_INET and AF_INET6 addresses and the * host itself can be multi-homed. Since we don't care whether we are * using ipv4 or ipv6, we just use the first address from this collection * in the order in which it was returned. * * The sorting function used within getaddrinfo() is defined in RFC 3484; * the order can be tweaked for a particular system by editing * /etc/gai.conf */ for (cai = ai, found = false; cai != NULL; cai = cai->ai_next) { si->family = cai->ai_family; si->addrlen = cai->ai_addrlen; nc_memcpy(&si->addr, cai->ai_addr, si->addrlen); found = true; break; } freeaddrinfo(ai); return !found ? -1 : 0; }
/* * Copy n bytes from memory area pos to mbuf. * * The memory areas should not overlap and the mbuf should have * enough space for n bytes. */ void mbuf_copy(struct mbuf *mbuf, uint8_t *pos, size_t n) { if (n == 0) { return; } /* mbuf has space for n bytes */ ASSERT(!mbuf_full(mbuf) && n <= mbuf_size(mbuf)); /* no overlapping copy */ ASSERT(pos < mbuf->start || pos >= mbuf->end); nc_memcpy(mbuf->last, pos, n); mbuf->last += n; }
/** *文件套接宇 */ static int nc_resolve_unix(struct string *name, struct sockinfo *si) { struct sockaddr_un *un; if (name->len >= NC_UNIX_ADDRSTRLEN) { return -1; } un = &si->addr.un; un->sun_family = AF_UNIX; nc_memcpy(un->sun_path, name->data, name->len); un->sun_path[name->len] = '\0'; si->family = AF_UNIX; si->addrlen = sizeof(*un); /* si->addr is an alias of un */ return 0; }
int tcp_connect(nsp_state *N, TCP_SOCKET *sock, char *host, unsigned short port, short int use_ssl) { #define __FN__ __FILE__ ":tcp_connect()" struct hostent *hp; struct sockaddr_in serv; if ((hp = gethostbyname(host)) == NULL) { n_warn(N, __FN__, "Host lookup error for %s", host); return -1; } nc_memset((char *)&serv, 0, sizeof(serv)); nc_memcpy((char *)&serv.sin_addr, hp->h_addr, hp->h_length); serv.sin_family = hp->h_addrtype; serv.sin_port = htons(port); if ((sock->socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) return -2; /* setsockopt(sock->socket, SOL_SOCKET, SO_KEEPALIVE, 0, 0); */ if (tcp_conn(N, sock, &serv, sizeof(serv), use_ssl) < 0) { /* n_warn(N, __FN__, "Error connecting to %s:%d", host, port); */ return -2; } return 0; #undef __FN__ }
rstatus_t conf_sentinel_each_transform(void *elem, void *data) { struct conf_server *cs = elem; struct array *server = data; struct server *s; ASSERT(cs->valid); s = array_push(server); ASSERT(s != NULL); s->idx = array_idx(server, s); s->owner = NULL; s->pname = cs->pname;/* ref */ s->name = cs->name;/* ref */ s->addrstr = cs->addrstr;/* ref */ s->port = (uint16_t)cs->port; s->weight = 1; nc_memcpy(&s->info, &cs->info, sizeof(cs->info)); s->ns_conn_q = 0; TAILQ_INIT(&s->s_conn_q); s->timer = msg_get_raw(server); if (s->timer == NULL) { return NC_ERROR; } s->status = 0; log_debug(LOG_VERB, "transform to sentinel %"PRIu32" '%.*s'", s->idx, s->pname.len, s->pname.data); return NC_OK; }
int tcp_bind(nsp_state *N, char *ifname, unsigned short port) { #define __FN__ __FILE__ ":tcp_bind()" struct hostent *hp; struct sockaddr_in sin; int option; int sock; nc_memset((char *)&sin, 0, sizeof(sin)); sock = socket(AF_INET, SOCK_STREAM, 0); sin.sin_family = AF_INET; if (strcasecmp("INADDR_ANY", ifname) == 0) { sin.sin_addr.s_addr = htonl(INADDR_ANY); } else { if ((hp = gethostbyname(ifname)) == NULL) { n_warn(N, __FN__, "Host lookup error for %s", ifname); return -1; } nc_memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length); } sin.sin_port = htons(port); option = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option)); if (bind(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { n_warn(N, __FN__, "bind() error [%s:%d]", ifname, port); return -1; } if (listen(sock, 50) < 0) { n_warn(N, __FN__, "listen() error"); closesocket(sock); return -1; } return sock; #undef __FN__ }
int tcp_fgets(nsp_state *N, TCP_SOCKET *socket, char *buffer, int max) { #define __FN__ __FILE__ ":tcp_fgets()" char *pbuffer = buffer; char *obuffer; short int lf = 0; short int n = 0; int rc; int x; retry: if (!socket->recvbufsize) { x = sizeof(socket->recvbuf) - socket->recvbufoffset - socket->recvbufsize - 2; if (x < 1) { nc_memset(socket->recvbuf, 0, sizeof(socket->recvbuf)); socket->recvbufoffset = 0; socket->recvbufsize = 0; x = sizeof(socket->recvbuf) - socket->recvbufoffset - socket->recvbufsize - 2; } obuffer = socket->recvbuf + socket->recvbufoffset + socket->recvbufsize; if (x > max) x = max; if ((rc = tcp_recv(N, socket, obuffer, x, 0)) < 0) { return -1; } else if (rc < 1) { /* goto retry; */ *pbuffer = '\0'; return n; } socket->recvbufsize += rc; } obuffer = socket->recvbuf + socket->recvbufoffset; while ((n < max) && (socket->recvbufsize>0)) { socket->recvbufoffset++; socket->recvbufsize--; n++; if (*obuffer == '\n') lf = 1; *pbuffer++ = *obuffer++; if ((lf) || (*obuffer == '\0')) break; } *pbuffer = '\0'; if (n > max - 1) { /* if (N->debug) n_warn(N, __FN__, "[%s:%d] %s", socket->RemoteAddr, socket->RemotePort, buffer); */ return n; } if (!lf) { if (socket->recvbufsize > 0) { nc_memcpy(socket->recvbuf, socket->recvbuf + socket->recvbufoffset, socket->recvbufsize); nc_memset(socket->recvbuf + socket->recvbufsize, 0, sizeof(socket->recvbuf) - socket->recvbufsize); socket->recvbufoffset = 0; } else { nc_memset(socket->recvbuf, 0, sizeof(socket->recvbuf)); socket->recvbufoffset = 0; socket->recvbufsize = 0; } goto retry; } /* if (N->debug) n_warn(N, __FN__, "[%s:%d] %s", socket->RemoteAddr, socket->RemotePort, buffer); */ return n; #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; }
//从elem conf_pool中拷贝到data server_pool目标中 rstatus_t conf_pool_each_transform(void *elem, void *data) { rstatus_t status; struct conf_pool *cp = elem; struct array *server_pool = data; struct server_pool *sp; ASSERT(cp->valid); sp = array_push(server_pool); ASSERT(sp != NULL); sp->idx = array_idx(server_pool, sp); sp->ctx = NULL; sp->p_conn = NULL; sp->nc_conn_q = 0; TAILQ_INIT(&sp->c_conn_q); array_null(&sp->server); sp->ncontinuum = 0; sp->nserver_continuum = 0; sp->continuum = NULL; sp->nlive_server = 0; sp->next_rebuild = 0LL; sp->name = cp->name; sp->addrstr = cp->listen.pname; sp->port = (uint16_t)cp->listen.port; nc_memcpy(&sp->info, &cp->listen.info, sizeof(cp->listen.info)); sp->perm = cp->listen.perm; sp->key_hash_type = cp->hash; sp->key_hash = hash_algos[cp->hash]; sp->dist_type = cp->distribution; sp->hash_tag = cp->hash_tag; sp->tcpkeepalive = cp->tcpkeepalive ? 1 : 0; sp->redis = cp->redis ? 1 : 0; sp->timeout = cp->timeout; sp->backlog = cp->backlog; sp->redis_db = cp->redis_db; sp->redis_auth = cp->redis_auth; sp->require_auth = cp->redis_auth.len > 0 ? 1 : 0; sp->client_connections = (uint32_t)cp->client_connections; sp->server_connections = (uint32_t)cp->server_connections; sp->server_retry_timeout = (int64_t)cp->server_retry_timeout * 1000LL; sp->server_failure_limit = (uint32_t)cp->server_failure_limit; sp->auto_eject_hosts = cp->auto_eject_hosts ? 1 : 0; sp->preconnect = cp->preconnect ? 1 : 0; status = server_init(&sp->server, &cp->server, sp); if (status != NC_OK) { return status; } log_debug(LOG_VERB, "transform to pool %"PRIu32" '%.*s'", sp->idx, sp->name.len, sp->name.data); 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__ }