static char *expand_line_buf(char *line, size_t cur_size, size_t required) { size_t new_size = cur_size; /* determine the new size */ do { new_size *= 2; } while (new_size < required); /* reallocate */ if (cur_size == LOG_ALLOCA_SIZE) { char *newpt = h2o_malloc(new_size); memcpy(newpt, line, cur_size); line = newpt; } else { line = h2o_realloc(line, new_size); } return line; }
static int on_config_listen(h2o_configurator_command_t *cmd, h2o_configurator_context_t *ctx, const char *config_file, yoml_t *config_node) { struct config_t *conf = H2O_STRUCT_FROM_MEMBER(struct config_t, global_config, ctx->globalconf); const char *hostname = NULL, *servname = NULL; SSL_CTX *ssl_ctx = NULL; struct addrinfo hints, *res; int error; /* fetch servname (and hostname) */ switch (config_node->type) { case YOML_TYPE_SCALAR: servname = config_node->data.scalar; break; case YOML_TYPE_MAPPING: { yoml_t *t; if ((t = yoml_get(config_node, "host")) != NULL) { if (t->type != YOML_TYPE_SCALAR) { h2o_config_print_error(cmd, config_file, t, "`host` is not a string"); return -1; } hostname = t->data.scalar; } if ((t = yoml_get(config_node, "port")) == NULL) { h2o_config_print_error(cmd, config_file, config_node, "cannot find mandatory property `port`"); return -1; } if (t->type != YOML_TYPE_SCALAR) { h2o_config_print_error(cmd, config_file, config_node, "`port` is not a string"); return -1; } servname = t->data.scalar; if ((t = yoml_get(config_node, "ssl")) != NULL) { if ((ssl_ctx = on_config_listen_setup_ssl(cmd, config_file, t)) == NULL) return -1; } } break; default: h2o_config_print_error(cmd, config_file, config_node, "value must be a string or a mapping (with keys: `port` and optionally `host`)"); return -1; } /* call getaddrinfo */ memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV | AI_PASSIVE; if ((error = getaddrinfo(hostname, servname, &hints, &res)) != 0) { h2o_config_print_error(cmd, config_file, config_node, "failed to resolve the listening address: %s", gai_strerror(error)); return -1; } else if (res == NULL) { h2o_config_print_error(cmd, config_file, config_node, "failed to resolve the listening address: getaddrinfo returned an empty list"); return -1; } { /* save the entries */ struct addrinfo *ai; for (ai = res; ai != NULL; ai = ai->ai_next) { struct listener_config_t *listener = h2o_malloc(sizeof(*listener)); listener->fd = -1; listener->family = ai->ai_family; listener->socktype = ai->ai_socktype; listener->protocol = ai->ai_protocol; memcpy(&listener->addr, ai->ai_addr, ai->ai_addrlen); listener->addrlen = ai->ai_addrlen; listener->ssl_ctx = ssl_ctx; conf->listeners = h2o_realloc(conf->listeners, sizeof(*conf->listeners) * (conf->num_listeners + 1)); conf->listeners[conf->num_listeners++] = listener; } } /* release res */ freeaddrinfo(res); return 0; }