示例#1
0
static int fpm_socket_af_inet_socket_by_addr(struct fpm_worker_pool_s *wp, const char *addr, const char *port) /* {{{ */
{
	struct addrinfo hints, *servinfo, *p;
	char tmpbuf[INET6_ADDRSTRLEN];
	int status;
	int sock = -1;

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if ((status = getaddrinfo(addr, port, &hints, &servinfo)) != 0) {
		zlog(ZLOG_ERROR, "getaddrinfo: %s\n", gai_strerror(status));
		return -1;
	}

	for (p = servinfo; p != NULL; p = p->ai_next) {
		inet_ntop(p->ai_family, fpm_get_in_addr(p->ai_addr), tmpbuf, INET6_ADDRSTRLEN);
		if (sock < 0) {
			if ((sock = fpm_sockets_get_listening_socket(wp, p->ai_addr, p->ai_addrlen)) != -1) {
				zlog(ZLOG_DEBUG, "Found address for %s, socket opened on %s", addr, tmpbuf);
			}
		} else {
			zlog(ZLOG_WARNING, "Found multiple addresses for %s, %s ignored", addr, tmpbuf);
		}
	}

	freeaddrinfo(servinfo);

	return sock;
}
示例#2
0
static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) /* {{{ */
{
    struct addrinfo hints, *servinfo, *p;
    char *dup_address = strdup(wp->config->listen_address);
    char *port_str = strrchr(dup_address, ':');
    char *addr = NULL;
    char tmpbuf[INET6_ADDRSTRLEN];
    int addr_len;
    int port = 0;
    int sock = -1;
    int status;

    if (port_str) { /* this is host:port pair */
        *port_str++ = '\0';
        port = atoi(port_str);
        addr = dup_address;
    } else if (strlen(dup_address) == strspn(dup_address, "0123456789")) { /* this is port */
        port = atoi(dup_address);
        port_str = dup_address;
        /* IPv6 catch-all + IPv4-mapped */
        addr = "::";
    }

    if (port == 0) {
        zlog(ZLOG_ERROR, "invalid port value '%s'", port_str);
        return -1;
    }

    /* strip brackets from address for getaddrinfo */
    addr_len = strlen(addr);
    if (addr[0] == '[' && addr[addr_len - 1] == ']') {
        addr[addr_len - 1] = '\0';
        addr++;
    }

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;

    if ((status = getaddrinfo(addr, port_str, &hints, &servinfo)) != 0) {
        zlog(ZLOG_ERROR, "getaddrinfo: %s\n", gai_strerror(status));
        return -1;
    }

    for (p = servinfo; p != NULL; p = p->ai_next) {
        inet_ntop(p->ai_family, fpm_get_in_addr(p->ai_addr), tmpbuf, INET6_ADDRSTRLEN);
        if (sock < 0) {
            if ((sock = fpm_sockets_get_listening_socket(wp, p->ai_addr, p->ai_addrlen)) != -1) {
                zlog(ZLOG_DEBUG, "Found address for %s, socket opened on %s", addr, tmpbuf);
            }
        } else {
            zlog(ZLOG_WARNING, "Found multiple addresses for %s, %s ignored", addr, tmpbuf);
        }
    }

    free(dup_address);
    freeaddrinfo(servinfo);

    return sock;
}
示例#3
0
static int fpm_sockets_hash_op(int sock, struct sockaddr *sa, char *key, int type, int op) /* {{{ */
{
	if (key == NULL) {
		switch (type) {
			case FPM_AF_INET : {
				key = alloca(INET6_ADDRSTRLEN+10);
				inet_ntop(sa->sa_family, fpm_get_in_addr(sa), key, INET6_ADDRSTRLEN);
				sprintf(key+strlen(key), ":%d", fpm_get_in_port(sa));
				break;
			}

			case FPM_AF_UNIX : {
				struct sockaddr_un *sa_un = (struct sockaddr_un *) sa;
				key = alloca(strlen(sa_un->sun_path) + 1);
				strcpy(key, sa_un->sun_path);
				break;
			}

			default :
				return -1;
		}
	}

	switch (op) {

		case FPM_GET_USE_SOCKET :
		{
			unsigned i;
			struct listening_socket_s *ls = sockets_list.data;

			for (i = 0; i < sockets_list.used; i++, ls++) {
				if (!strcmp(ls->key, key)) {
					++ls->refcount;
					return ls->sock;
				}
			}
			break;
		}

		case FPM_STORE_SOCKET :			/* inherited socket */
		case FPM_STORE_USE_SOCKET :		/* just created */
		{
			struct listening_socket_s *ls;

			ls = fpm_array_push(&sockets_list);
			if (!ls) {
				break;
			}

			if (op == FPM_STORE_SOCKET) {
				ls->refcount = 0;
			} else {
				ls->refcount = 1;
			}
			ls->type = type;
			ls->sock = sock;
			ls->key = strdup(key);

			return 0;
		}
	}
	return -1;
}
示例#4
0
static int fpm_socket_af_inet_listening_socket(struct fpm_worker_pool_s *wp) /* {{{ */
{
	struct addrinfo hints, *servinfo, *p;
	char *dup_address = strdup(wp->config->listen_address);
	// 获取port
	char *port_str = strrchr(dup_address, ':');
	char *addr = NULL;
	char tmpbuf[INET6_ADDRSTRLEN];
	int addr_len;
	int port = 0;
	int sock = -1;
	int status;

	if (port_str) { /* this is host:port pair */
		*port_str++ = '\0';
		port = atoi(port_str);
		addr = dup_address;
	} else if (strlen(dup_address) == strspn(dup_address, "0123456789")) { /* this is port */
		port = atoi(dup_address);
		port_str = dup_address;
	}

	if (port == 0) {
		zlog(ZLOG_ERROR, "invalid port value '%s'", port_str);
		return -1;
	}

	if (!addr) {
		/* no address: default documented behavior, all IPv4 addresses */
		struct sockaddr_in sa_in;

		memset(&sa_in, 0, sizeof(sa_in));
		sa_in.sin_family = AF_INET;
		sa_in.sin_port = htons(port);
		sa_in.sin_addr.s_addr = htonl(INADDR_ANY);
		free(dup_address);
		return fpm_sockets_get_listening_socket(wp, (struct sockaddr *) &sa_in, sizeof(struct sockaddr_in));
	}

	/* strip brackets from address for getaddrinfo */
	addr_len = strlen(addr);
	if (addr[0] == '[' && addr[addr_len - 1] == ']') {
		addr[addr_len - 1] = '\0';
		addr++;
	}

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	zlog(ZLOG_NOTICE, "pa -> func : 监听socket, addr[%s]", addr);
	if ((status = getaddrinfo(addr, port_str, &hints, &servinfo)) != 0) {
		zlog(ZLOG_ERROR, "getaddrinfo: %s\n", gai_strerror(status));
		free(dup_address);
		return -1;
	}

	for (p = servinfo; p != NULL; p = p->ai_next) {
		inet_ntop(p->ai_family, fpm_get_in_addr(p->ai_addr), tmpbuf, INET6_ADDRSTRLEN);
		if (sock < 0) {
			if ((sock = fpm_sockets_get_listening_socket(wp, p->ai_addr, p->ai_addrlen)) != -1) {
				zlog(ZLOG_DEBUG, "Found address for %s, socket opened on %s", dup_address, tmpbuf);
			}
		} else {
			zlog(ZLOG_WARNING, "Found multiple addresses for %s, %s ignored", dup_address, tmpbuf);
		}
	}

	free(dup_address);
	freeaddrinfo(servinfo);

	return sock;
}