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; }
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; }
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; }
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; }