示例#1
0
文件: tcp.c 项目: Toeger/f-irc
int setup_nonblocking_socket(void)
{
	/* create socket */
	int handle = socket(AF_INET, SOCK_STREAM, 0);

	if (handle == -1)
		return -1;

	/* set fd to non-blocking */
	if (fcntl(handle, F_SETFL, O_NONBLOCK) == -1)
	{
		int e = errno;

		close(handle);

		errno = e;

		return -1;
	}

	set_ka(handle);

	set_no_delay(handle);

	return handle;
}
示例#2
0
文件: tcp.c 项目: Toeger/f-irc
int connect_to(resolve_info *ri, char **message)
{
	struct addrinfo *rp = ri -> alist[ri -> index];

	int fd = socket(rp -> ai_family, rp -> ai_socktype, rp -> ai_protocol);
	if (fd == -1)
	{
		asprintf(message, "could not create socket: %s (%d)", strerror(errno), errno);
		ri -> index = (ri -> index + 1) % ri -> alist_n;
		return -1;
	}

	if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1)
	{
		asprintf(message, "fcnt(O_NONBLOCK) failed: %s (%d)", strerror(errno), errno);
		close(fd);
		ri -> index = (ri -> index + 1) % ri -> alist_n;
		return -1;
	}

	set_ka(fd);

	set_no_delay(fd);

	/* connect to peer */
	if (connect(fd, rp -> ai_addr, rp -> ai_addrlen) == 0)
		return fd;

	if (errno == EINPROGRESS)
	{
		/* not yet made but might be fine*/
		return fd;
	}

	asprintf(message, "connect failed: %s (%d)", strerror(errno), errno);

	close(fd);

	ri -> index = (ri -> index + 1) % ri -> alist_n;

	return -1;
}
示例#3
0
文件: tcp.c 项目: ChenKaiJung/HTTPing
int create_socket(struct sockaddr *bind_to, struct addrinfo *ai, int recv_buffer_size, int tx_buffer_size, int max_mtu, char use_no_delay, int priority, int tos)
{
	int fd = -1;

	/* create socket */
	fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
	if (fd == -1)
	{
		set_error(gettext("problem creating socket (%s)"), strerror(errno));
		return RC_INVAL;
	}

	/* go through a specific interface? */
	if (bind_to)
	{
		int set = 1;

		/* set reuse flags */
		if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &set, sizeof set) == -1)
		{
			set_error(gettext("error setting sockopt to interface (%s)"), strerror(errno));
			return RC_INVAL;
		}

		if (bind(fd, bind_to, sizeof *bind_to) == -1)
		{
			set_error(gettext("error binding to interface (%s)"), strerror(errno));
			return RC_INVAL;
		}
	}

	if (max_mtu >= 0)
	{
		if (setsockopt(fd, IPPROTO_TCP, TCP_MAXSEG, &max_mtu, sizeof max_mtu) == -1)
		{
			set_error(gettext("error setting MTU size (%s)"), strerror(errno));
			return RC_INVAL;
		}
	}

	if (use_no_delay)
	{
		int rc = -1;

		if ((rc = set_no_delay(fd)) != 0)
			return rc;
	}

	if (tx_buffer_size > 0)
        {
		if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&tx_buffer_size, sizeof tx_buffer_size) == -1)
		{
			set_error(gettext("error setting transmit buffer size (%s)"), strerror(errno));
			return RC_INVAL;
		}
	}

	if (recv_buffer_size > 0)
        {
		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&recv_buffer_size, sizeof recv_buffer_size) == -1)
		{
			set_error(gettext("error setting receive buffer size (%s)"), strerror(errno));
			return RC_INVAL;
		}
	}

#ifdef linux
	if (priority >= 0)
	{
		if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (char *)&priority, sizeof priority) == -1)
		{
			set_error(gettext("error setting priority (%s)"), strerror(errno));
			return RC_INVAL;
		}
	}
#endif

	if (tos >= 0)
	{
		if (setsockopt(fd, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof tos) == -1)
		{
			set_error(gettext("failed to set TOS info"));
			return RC_INVAL;
		}
	}

	return fd;
}
示例#4
0
static
struct conn_t *conn_new(struct sockaddr_in *raddr, struct sockaddr_in *laddr) {
    struct conn_t *c;
    int lsize, errnosave;
    struct sockaddr_in tmp;

    c = smalloc(sizeof(*c));
    memset(c, 0, sizeof(*c));
    c->state = CONN_NEW;
    INIT_LIST_HEAD(&c->reqs);

    if ((c->fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
	errnosave = errno;
	syslog(LOG_ERR, "socket: %s", strerror(errno));
	free(c);
	errno = errnosave;
	return 0;
    }

    /* If this is not the first connection, do a non-blocking connect */
    if (!list_empty(&clist))
	set_non_block(c->fd);

    tmp = *laddr;		/* use a temp here because
				 * bindresvport writes it. */
    if (laddr->sin_port ||
	bindresvport(c->fd, &tmp) == -1) {
	    syslog(LOG_ERR, "bindresvport: %s (ignoring)", strerror(errno));
	    /* If we specified a port or failed to bind to a reserved
	     * port for some reason, try a normal bind. */
	    if (bind(c->fd, (struct sockaddr *) laddr, sizeof(*laddr)) == -1) {
		errnosave = errno;
		syslog(LOG_ERR, "bind(%s:%d): %s (ignoring)",
		       inet_ntoa(laddr->sin_addr), ntohs(laddr->sin_port),
		       strerror(errno));
		close(c->fd);
		free(c);
		errno = errnosave;
		return 0;
	    }
    }

    if (verbose)
	syslog(LOG_INFO, "Connecting to %s:%d...",
	       inet_ntoa(raddr->sin_addr), ntohs(raddr->sin_port));

    if (connect(c->fd, (struct sockaddr *) raddr, sizeof(*raddr)) == -1) {
	if (errno != EINPROGRESS) {
	    errnosave = errno;
	    syslog(LOG_ERR, "connect(%s:%d): %s",
		   inet_ntoa(raddr->sin_addr), ntohs(raddr->sin_port),
		   strerror(errno));
	    close(c->fd);
	    free(c);
	    errno = errnosave;
	    return 0;
	}
    }

    /* Make note of our local address */
    lsize = sizeof(c->laddr);
    getsockname(c->fd, (struct sockaddr *)&c->laddr, &lsize);
    c->raddr = *raddr;

    /* Prime output buffer with version information and cookie */
    conn_send_version(c);

    set_keep_alive(c->fd);
    set_no_delay(c->fd);
    set_non_block(c->fd);

    /* Append to list of connections */
    list_add_tail(&c->list, &clist);
    return c;
}
示例#5
0
		void start()
		{
			set_no_delay();
			do_read();
		}