Beispiel #1
0
static void
nc_set_default_options(struct instance *nci)
{
    int status;

    nci->ctx = NULL;

    nci->log_level = NC_LOG_DEFAULT;
    nci->log_filename = NC_LOG_PATH;

    nci->conf_filename = NC_CONF_PATH;

    nci->stats_port = NC_STATS_PORT;
    nci->stats_addr = NC_STATS_ADDR;
    nci->stats_interval = NC_STATS_INTERVAL;

    status = nc_gethostname(nci->hostname, NC_MAXHOSTNAMELEN);
    if (status < 0) {
        log_warn("gethostname failed, ignored: %s", strerror(errno));
        nc_snprintf(nci->hostname, NC_MAXHOSTNAMELEN, "unknown");
    }
    nci->hostname[NC_MAXHOSTNAMELEN - 1] = '\0';

    nci->mbuf_chunk_size = NC_MBUF_SIZE;
    nci->mbuf_pool_size = NC_MBUF_POOL_SIZE;

    nci->pid = (pid_t)-1;
    nci->pid_filename = NULL;
    nci->pidfile = 0;
}
Beispiel #2
0
static rstatus_t
nc_create_pidfile(struct instance *nci)
{
    char pid[NC_UINTMAX_MAXLEN];
    int fd, pid_len;
    ssize_t n;

    fd = open(nci->pid_filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd < 0) {
        log_error("opening pid file '%s' failed: %s", nci->pid_filename,
                  strerror(errno));
        return NC_ERROR;
    }
    nci->pidfile = 1;

    pid_len = nc_snprintf(pid, NC_UINTMAX_MAXLEN, "%d", nci->pid);

    n = nc_write(fd, pid, pid_len);
    if (n < 0) {
        log_error("write to pid file '%s' failed: %s", nci->pid_filename,
                  strerror(errno));
        return NC_ERROR;
    }

    close(fd);

    return NC_OK;
}
Beispiel #3
0
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;
}
Beispiel #4
0
/*
 * Unresolve the socket address by translating it to a character string
 * describing the host and service
 * 返回地址字符串
 * This routine is not reentrant
 */
char *
nc_unresolve_addr(struct sockaddr *addr, socklen_t addrlen)
{
    static char unresolve[NI_MAXHOST + NI_MAXSERV];
    static char host[NI_MAXHOST], service[NI_MAXSERV];
    int status;

    status = getnameinfo(addr, addrlen, host, sizeof(host),
                         service, sizeof(service),
                         NI_NUMERICHOST | NI_NUMERICSERV);
    if (status < 0) {
        return "unknown";
    }

    nc_snprintf(unresolve, sizeof(unresolve), "%s:%s", host, service);

    return unresolve;
}
Beispiel #5
0
static rstatus_t
stats_begin_nesting(struct stats *st, struct string *key)
{
    struct stats_buffer *buf;
    uint8_t *pos;
    size_t room;
    int n;

    buf = &st->buf;
    pos = buf->data + buf->len;
    room = buf->size - buf->len - 1;

    n = nc_snprintf(pos, room, "\"%.*s\": {", key->len, key->data);
    if (n < 0 || n >= (int)room) {
        return NC_ERROR;
    }

    buf->len += (size_t)n;

    return NC_OK;
}
Beispiel #6
0
static rstatus_t
stats_add_float(struct stats *st, struct string *key, float val)
{
    struct stats_buffer *buf;
    uint8_t *pos;
    size_t room;
    int n;

    buf = &st->buf;
    pos = buf->data + buf->len;
    room = buf->size - buf->len - 1;

    n = nc_snprintf(pos, room, "\"%.*s\":%.2f, ", key->len, key->data, val);
    if (n < 0 || n >= (int)room) {
        return NC_ERROR;
    }

    buf->len += (size_t)n;

    return NC_OK;
}
Beispiel #7
0
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;
}