예제 #1
0
int
glb_socket_create (const struct sockaddr_in* addr)
{
    int sock;
//    size_t buf_size = 1024;

    /* Create the socket. */
    sock = socket (PF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        glb_log_error ("Failed to create listening socket: %d (%s)",
                       errno, strerror (errno));
        return -errno;
    }
#if 0
    /* probably a good place to specify some socket options */
    if (setsockopt (sock, SOL_SOCKET, SO_RCVBUF, &buf_size, sizeof(buf_size))) {
        glb_log_error ("setsockopt() failed: %d (%s)", -errno, strerror(errno));
        close (sock);
        return -errno;
    }

    if (setsockopt (sock, SOL_SOCKET, SO_SNDBUF, &buf_size, sizeof(buf_size))) {
        glb_log_error ("setsockopt() failed: %d (%s)", -errno, strerror(errno));
        close (sock);
        return -errno;
    }
#endif
    /* Give the socket a name. */
    if (bind (sock, (struct sockaddr *) addr, sizeof (*addr)) < 0)
    {
        glb_log_error ("Failed to bind listening socket: %d (%s)",
                       errno, strerror (errno));
        close (sock);
        return -errno;
    }

    return sock;
}
예제 #2
0
// returns socket number or negative error code
int
glb_router_connect (glb_router_t* router, glb_sockaddr_t* dst_addr)
{
    int sock, ret;

    // prepare a socket
    sock = glb_socket_create (&router->sock_out);
    if (sock < 0) {
        glb_log_error ("glb_socket_create() failed");
        return sock;
    }

    // attmept to connect until we run out of destinations
    ret = router_connect_dst (router, sock, dst_addr);

    // avoid socket leak
    if (ret < 0) {
        glb_log_error ("router_connect_dst() failed");
        close (sock);
	sock = ret;
    }

    return sock;
}
예제 #3
0
// Initialize glb_sockaddr_t struct
long
glb_socket_addr_init (glb_sockaddr_t* addr,
                      const char*     hostname,
                      uint16_t        port)
{
    struct hostent *host;

    host = gethostbyname (hostname);
    if (host == NULL)
    {
        glb_log_error ("Unknown host %s.\n", hostname);
        return -EINVAL;
    }
    addr->sin_addr = *(struct in_addr *) host->h_addr;
    addr->sin_port   = htons (port);
    addr->sin_family = AF_INET;

    return 0;
}
예제 #4
0
파일: glb_dst.c 프로젝트: Zlo/glb
// parses addr:port:weight string, stores in dst
// returns number of parsed fields or negative error code
long
glb_dst_parse (glb_dst_t* dst, const char* s, uint16_t default_port)
{
    const char* token;
    char*       endptr;
    char        addr_str[dst_ip_len_max + 1] = { 0, };
    ptrdiff_t   addr_len;
    ulong       port = default_port;
    long        ret  = 0;

    dst->weight = dst_default_weight;

    // parse IP address
    endptr = strchr (s, dst_separator);

    if (NULL != endptr)
        addr_len = endptr - s;
    else
        addr_len = strlen (s);
    if (addr_len > dst_ip_len_max) {
        glb_log_error ("Host address too long: %s\n", s);
        return -EINVAL;
    }

    strncpy (addr_str, s, addr_len); // this now contains only host address

    ret = 1;
    if (NULL == endptr) // string is over
        goto end;

    // parse port
    assert (*endptr == dst_separator);
    token = endptr + 1;
    port = strtoul (token, &endptr, 10);
    if (*endptr != dst_separator  &&
        *endptr != '\0') {
        glb_log_error ("Port field doesn't consist only of numbers");
        return -EINVAL;
    }
    if (port > dst_port_max) {
        // value of 0 means no setting, don't check
        glb_log_error ("Port value exceeds maximum port number");
        return -EINVAL;
    }

    ret = 2;
    if (*endptr == '\0') // string is over
        goto end;

    // parse weight
    assert (*endptr == dst_separator);
    token = endptr + 1;
    dst->weight = strtod (token, &endptr);
    if (*endptr != '\0') {
        glb_log_error ("Weight field doesn't consist only of numbers");
        return -EINVAL;
    }
    ret = 3;

end:
    if (glb_sockaddr_init (&dst->addr, addr_str, port)) {
        glb_log_error ("%s", strerror (EINVAL));
        return -EINVAL;
    }

    return ret;
}