Ejemplo n.º 1
0
/* host->lock must be held when calling this function. */
static int wrr_connect(struct riemann_host *host) /* {{{ */
{
  char const *node;
  int port;

  if (host->client)
    return 0;

  node = (host->node != NULL) ? host->node : RIEMANN_HOST;
  port = (host->port) ? host->port : RIEMANN_PORT;

  host->client = NULL;

  host->client = riemann_client_create(
      host->client_type, node, port, RIEMANN_CLIENT_OPTION_TLS_CA_FILE,
      host->tls_ca_file, RIEMANN_CLIENT_OPTION_TLS_CERT_FILE,
      host->tls_cert_file, RIEMANN_CLIENT_OPTION_TLS_KEY_FILE,
      host->tls_key_file, RIEMANN_CLIENT_OPTION_NONE);
  if (host->client == NULL) {
    c_complain(LOG_ERR, &host->init_complaint,
               "write_riemann plugin: Unable to connect to Riemann at %s:%d",
               node, port);
    return -1;
  }
#if RCC_VERSION_NUMBER >= 0x010800
  if (host->timeout.tv_sec != 0) {
    if (riemann_client_set_timeout(host->client, &host->timeout) != 0) {
      riemann_client_free(host->client);
      host->client = NULL;
      c_complain(LOG_ERR, &host->init_complaint,
                 "write_riemann plugin: Unable to connect to Riemann at %s:%d",
                 node, port);
      return -1;
    }
  }
#endif

  set_sock_opts(riemann_client_get_fd(host->client));

  c_release(LOG_INFO, &host->init_complaint,
            "write_riemann plugin: Successfully connected to %s:%d", node,
            port);

  return 0;
} /* }}} int wrr_connect */
Ejemplo n.º 2
0
static int wg_callback_init (struct wg_callback *cb)
{
    struct addrinfo *ai_list;
    cdtime_t now;
    int status;

    char connerr[1024] = "";

    if (cb->sock_fd > 0)
        return (0);

    /* Don't try to reconnect too often. By default, one reconnection attempt
     * is made per second. */
    now = cdtime ();
    if ((now - cb->last_connect_time) < WG_MIN_RECONNECT_INTERVAL)
        return (EAGAIN);
    cb->last_connect_time = now;

    struct addrinfo ai_hints = {
        .ai_family = AF_UNSPEC,
        .ai_flags  = AI_ADDRCONFIG
    };

    if (0 == strcasecmp ("tcp", cb->protocol))
        ai_hints.ai_socktype = SOCK_STREAM;
    else
        ai_hints.ai_socktype = SOCK_DGRAM;

    status = getaddrinfo (cb->node, cb->service, &ai_hints, &ai_list);
    if (status != 0)
    {
        ERROR ("write_graphite plugin: getaddrinfo (%s, %s, %s) failed: %s",
                cb->node, cb->service, cb->protocol, gai_strerror (status));
        return (-1);
    }

    assert (ai_list != NULL);
    for (struct addrinfo *ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next)
    {
        cb->sock_fd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype,
                ai_ptr->ai_protocol);
        if (cb->sock_fd < 0) {
            char errbuf[1024];
            snprintf (connerr, sizeof (connerr), "failed to open socket: %s",
                    sstrerror (errno, errbuf, sizeof (errbuf)));
            continue;
        }

        set_sock_opts (cb->sock_fd);

        status = connect (cb->sock_fd, ai_ptr->ai_addr, ai_ptr->ai_addrlen);
        if (status != 0)
        {
            char errbuf[1024];
            snprintf (connerr, sizeof (connerr), "failed to connect to remote "
                    "host: %s", sstrerror (errno, errbuf, sizeof (errbuf)));
            close (cb->sock_fd);
            cb->sock_fd = -1;
            continue;
        }

        break;
    }

    freeaddrinfo (ai_list);

    if (cb->sock_fd < 0)
    {
        if (connerr[0] == '\0')
            /* this should not happen but try to get a message anyway */
            sstrerror (errno, connerr, sizeof (connerr));
        c_complain (LOG_ERR, &cb->init_complaint,
                  "write_graphite plugin: Connecting to %s:%s via %s failed. "
                  "The last error was: %s", cb->node, cb->service, cb->protocol, connerr);
        return (-1);
    }
    else
    {
        c_release (LOG_INFO, &cb->init_complaint,
                "write_graphite plugin: Successfully connected to %s:%s via %s.",
                cb->node, cb->service, cb->protocol);
    }

    /* wg_force_reconnect_check does not flush the buffer before closing a
     * sending socket, so only call wg_reset_buffer() if the socket was closed
     * for a different reason (tracked in cb->reconnect_interval_reached). */
    if (!cb->reconnect_interval_reached || (cb->send_buf_free == 0))
        wg_reset_buffer (cb);
    else
        cb->reconnect_interval_reached = 0;

    return (0);
}