コード例 #1
0
ファイル: rstream.c プロジェクト: simonzhangsm/librdmacm
static void set_options(int rs)
{
	int val;

	if (buffer_size) {
		rs_setsockopt(rs, SOL_SOCKET, SO_SNDBUF, (void *) &buffer_size,
			      sizeof buffer_size);
		rs_setsockopt(rs, SOL_SOCKET, SO_RCVBUF, (void *) &buffer_size,
			      sizeof buffer_size);
	} else {
		val = 1 << 19;
		rs_setsockopt(rs, SOL_SOCKET, SO_SNDBUF, (void *) &val, sizeof val);
		rs_setsockopt(rs, SOL_SOCKET, SO_RCVBUF, (void *) &val, sizeof val);
	}

	val = 1;
	rs_setsockopt(rs, IPPROTO_TCP, TCP_NODELAY, (void *) &val, sizeof(val));

	if (flags & MSG_DONTWAIT)
		rs_fcntl(rs, F_SETFL, O_NONBLOCK);

	if (use_rs) {
		/* Inline size based on experimental data */
		if (optimization == opt_latency) {
			val = 384;
			rs_setsockopt(rs, SOL_RDMA, RDMA_INLINE, &val, sizeof val);
		} else if (optimization == opt_bandwidth) {
			val = 0;
			rs_setsockopt(rs, SOL_RDMA, RDMA_INLINE, &val, sizeof val);
		}
	}

	if (keepalive)
		set_keepalive(rs);
}
コード例 #2
0
ファイル: srvevents.c プロジェクト: mpsnp/mchat-server
void on_connect(EV_P_ struct ev_io *io, int revents) {
    while (1) {
        struct sockaddr_in client_addr;
        socklen_t len = sizeof (struct sockaddr_in);
        int client_sock = accept(io->fd, (struct sockaddr *) &client_addr, &len);
        if (client_sock >= 0) {

            if (set_nonblock(client_sock) == -1) {
                shutdown_printerr(client_sock, "can't set the socket mode O_NONBLOCK for client\n");
                return;
            }

            if (set_linger(client_sock) == -1) {
                shutdown_printerr(client_sock, "can't set SO_LINGER sock option for client\n");
                return;
            }

            if (set_keepalive(client_sock) == -1) {
                shutdown_printerr(client_sock, "can't set SO_KEEPALIVE sock option for client\n");
                return;
            }

            server_ctx_t *srv_ctx = (server_ctx_t *) ev_userdata(loop);
            client_ctx_t* cli_ctx = get_client_ctx(srv_ctx);
            cli_ctx->io.ctx = cli_ctx;
            cli_ctx->connected_at = time(NULL);
            uuid_generate(cli_ctx->uuid);
            memcpy(&cli_ctx->client_addr, &client_addr, sizeof (struct sockaddr_in));
            ev_io_init((ev_io *) & cli_ctx->io, client_read_write, client_sock, EV_READ);
            ev_io_start(loop, (ev_io *) & cli_ctx->io);
            char time_buff[32];
            strftime(time_buff, sizeof (time_buff), "%Y-%m-%d %H:%M:%S %Z", localtime(&cli_ctx->connected_at));
            char *addr = inet_ntoa(cli_ctx->client_addr.sin_addr);
            char uuid_buff[37];
            uuid_unparse_lower(cli_ctx->uuid, (char *) &uuid_buff);
            printf("client accepted %s:%hu %s at %s\n", addr, client_addr.sin_port, &uuid_buff, &time_buff);
            char *welcome_msg = server_welcome(srv_ctx, cli_ctx);
            send_message(loop, cli_ctx->uuid, welcome_msg, strlen(welcome_msg));
            free(welcome_msg);
            char *new_client_msg = server_client_connected(cli_ctx);
            for (ssize_t i = 0; i < srv_ctx->clients_count; i++) {
                if (uuid_compare(srv_ctx->clients[i]->uuid, cli_ctx->uuid) != 0) {
                    send_message(loop, srv_ctx->clients[i]->uuid, new_client_msg, strlen(new_client_msg));
                }
            }
            free(new_client_msg);
        } else {
            if (errno == EAGAIN)
                return;
            if (errno == EMFILE || errno == ENFILE) {
                fprintf(stderr, "out of file descriptors\n");
                return;
            } else if (errno != EINTR) {
                fprintf(stderr, "accept connections error\n");
                return;
            }
        }
    }
}
コード例 #3
0
int socketio_setoption(CONCRETE_IO_HANDLE socket_io, const char* optionName, const void* value)
{
    int result;

    if (socket_io == NULL ||
            optionName == NULL ||
            value == NULL)
    {
        result = __LINE__;
    }
    else
    {
        SOCKET_IO_INSTANCE* socket_io_instance = (SOCKET_IO_INSTANCE*)socket_io;

        if (strcmp(optionName, "tcp_keepalive") == 0)
        {
            struct tcp_keepalive keepAlive = socket_io_instance->keep_alive;
            keepAlive.onoff = *(int *)value;

            result = set_keepalive(socket_io_instance, &keepAlive);
        }
        else if (strcmp(optionName, "tcp_keepalive_time") == 0)
        {
            unsigned long kaTime = *(int *)value * 1000; // convert to ms
            struct tcp_keepalive keepAlive = socket_io_instance->keep_alive;
            keepAlive.keepalivetime = kaTime;

            result = set_keepalive(socket_io_instance, &keepAlive);
        }
        else if (strcmp(optionName, "tcp_keepalive_interval") == 0)
        {
            unsigned long kaInterval = *(int *)value * 1000; // convert to ms
            struct tcp_keepalive keepAlive = socket_io_instance->keep_alive;
            keepAlive.keepaliveinterval = kaInterval;

            result = set_keepalive(socket_io_instance, &keepAlive);
        }
        else
        {
            result = __LINE__;
        }
    }

    return result;
}
コード例 #4
0
ファイル: send.c プロジェクト: jnbek/TekNap
void nap_chat_start(int snum)
{
GetFile *gf;
SocketList *s;

	if (!(s = get_socket(snum)) || !(gf = (GetFile *)s->info))
	{
		put_it("error get_socket(%d)", snum);
		nap_finished_file(snum, PREMATURE_FINISH);
		return;
	}
	if (gf->deleted)
	{
		if (gf->write != -1)
			close(gf->write);
		gf->write = -1;
		if (gf->deleted++ > 5)
			close_socketread(snum);
		return;
	}
	if ((gf->flags & NAP_CHAT) == NAP_CHAT)
	{
		/* we need to accept the connection here. */
		struct  sockaddr_in     remaddr;
		int sra = sizeof(struct sockaddr_in);
		int sock = -1;
		if ((sock = my_accept(snum, (struct sockaddr *) &remaddr, &sra)) > -1)
		{
			set_keepalive(sock);
			gf->port = ntohs(remaddr.sin_port);
			add_socketread(sock, gf->port, 0, inet_ntoa(remaddr.sin_addr), nap_chat, NULL);
			set_socketinfo(sock, gf);
			s->info = NULL;
			gf->flags = NAP_CHAT_CONNECTED;
			gf->socket = sock;
			malloc_strcpy(&gf->ip, inet_ntoa(remaddr.sin_addr));
			say("DCC CHAT to %s [%s:%d] established", gf->nick, gf->ip, gf->port);
			gf->starttime = now;
		}
		close_socketread(snum);
		return;
	}
}
コード例 #5
0
ファイル: network.c プロジェクト: khaytsus/opennap-ng
SOCKET make_tcp_connection(const char *host, unsigned short port, unsigned int *ip)
{
    struct sockaddr_in sin;
    SOCKET     f;

    memset(&sin, 0, sizeof(sin));
    sin.sin_port = htons(port);
    sin.sin_family = AF_INET;
    if((sin.sin_addr.s_addr = lookup_ip(host)) == 0)
        return INVALID_SOCKET;
    if(ip)
        *ip = sin.sin_addr.s_addr;
    if((f = new_tcp_socket(ON_NONBLOCKING)) == INVALID_SOCKET)
        return INVALID_SOCKET;

    /* if an interface was specify, bind to it before connecting */
    if(global.iface)
        bind_interface(f, global.iface, 0);

    /* turn on TCP/IP keepalive messages */
    set_keepalive(f, 1);
    log_message_level(LOG_LEVEL_DEBUG, "make_tcp_connection: connecting to %s:%hu", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
    if(connect(f, (struct sockaddr *) &sin, sizeof(sin)) < 0)
    {
        if(N_ERRNO != EINPROGRESS
#ifdef WIN32
            /* winsock returns EWOULDBLOCK even in nonblocking mode! ugh!!! */
            && N_ERRNO != EWOULDBLOCK
#endif
            )
        {
            nlogerr("make_tcp_connection", "connect");
            CLOSE(f);
            return INVALID_SOCKET;
        }
        log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection to %s in progress", host);
    }
    else
        log_message_level(LOG_LEVEL_SERVER, "make_tcp_connection: connection established to %s", host);
    return f;
}
コード例 #6
0
ファイル: oob_tcp_common.c プロジェクト: Slbomber/ompi
void orte_oob_tcp_set_socket_options(int sd)
{
#if defined(TCP_NODELAY)
    int optval;
    optval = 1;
    if (setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) < 0) {
        opal_backtrace_print(stderr, NULL, 1);
        opal_output_verbose(5, orte_oob_base_framework.framework_output,
                            "[%s:%d] setsockopt(TCP_NODELAY) failed: %s (%d)", 
                            __FILE__, __LINE__, 
                            strerror(opal_socket_errno),
                            opal_socket_errno);
    }
#endif
#if defined(SO_SNDBUF)
    if (mca_oob_tcp_component.tcp_sndbuf > 0 &&
        setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (char *)&mca_oob_tcp_component.tcp_sndbuf, sizeof(int)) < 0) {
        opal_output_verbose(5, orte_oob_base_framework.framework_output,
                            "[%s:%d] setsockopt(SO_SNDBUF) failed: %s (%d)", 
                            __FILE__, __LINE__, 
                            strerror(opal_socket_errno),
                            opal_socket_errno);
    }
#endif
#if defined(SO_RCVBUF)
    if (mca_oob_tcp_component.tcp_rcvbuf > 0 &&
        setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (char *)&mca_oob_tcp_component.tcp_rcvbuf, sizeof(int)) < 0) {
        opal_output_verbose(5, orte_oob_base_framework.framework_output,
                            "[%s:%d] setsockopt(SO_RCVBUF) failed: %s (%d)", 
                            __FILE__, __LINE__, 
                            strerror(opal_socket_errno),
                            opal_socket_errno);
    }
#endif

    if (0 < mca_oob_tcp_component.keepalive_time) {
        set_keepalive(sd);
    }
}
コード例 #7
0
static void *keepalive_thread(void *arg)
{
	int sock;
	int print_errmsg = 1;

	while (1) {
		sock = tcpconn(server_ip, server_port, 5);
		if (sock == -1) {
			if (print_errmsg == 1) {
				syslog(LOG_ERR, "connect app server failed.");
				print_errmsg = 0;
			}
			sleep(5);
			continue;
		}
		syslog(LOG_INFO, "connect app server success.");
		set_keepalive(sock, KEEPALIVE_IDEL, KEEPALIVE_CNT, 
				KEEPALIVE_INTV);

		LOCK(mtx);
		server_sock = sock;
		UNLOCK(mtx);

		dummy_recv_loop(server_sock);

		LOCK(mtx);
		close(server_sock);
		server_sock = INVALID_SOCKET;
		UNLOCK(mtx);
		syslog(LOG_INFO, "disconnect from app server.");

		print_errmsg = 1;
		sleep(5);
	}

	return NULL;
}
コード例 #8
0
ファイル: sysutil.c プロジェクト: sdwvskyo/C-Cplusplus
int tcp_server(const char *host, uint16_t port)
{
	//处理PIPE信号
	handle_sigpipe();

	int listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if (listenfd == -1)
		ERR_EXIT("socket");

	set_reuseaddr(listenfd, 1);
	set_reuseport(listenfd, 1);
	set_keepalive(listenfd, 0);
	set_tcpnodelay(listenfd, 0);

	SAI addr;
	memset(&addr, 0, sizeof addr);
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	if (host == NULL) {
		addr.sin_addr.s_addr = INADDR_ANY;
	} 
	else if (inet_aton(host, &addr.sin_addr) == 0) {
		struct hostent *hp = gethostbyname(host);
		if (hp == NULL)
			ERR_EXIT("gethostbyname");
		addr.sin_addr = *(struct in_addr *)hp->h_addr;
	}

	if (bind(listenfd, (SA *)&addr, sizeof addr) == -1)
		ERR_EXIT("bind");

	if (listen(listenfd, SOMAXCONN) == -1)
		ERR_EXIT("listen");

	return listenfd;
}
コード例 #9
0
void
reap_info_slave(void)
{
  struct response_dgram resp;
  ssize_t len;
  char hostname[BUFFER_LEN], *hp;
  int n, count;
  conn_source source;

  if (info_slave_state != INFO_SLAVE_PENDING) {
    if (info_slave_state == INFO_SLAVE_DOWN)
      make_info_slave();
    return;
  }

  len = recv(info_slave, &resp, sizeof resp, 0);
  if (len < 0 && (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
    return;
  else if (len < 0 || len != (int) sizeof resp) {
    penn_perror("reading info_slave response");
    return;
  }

  /* okay, now we have some info! */
  if (!FD_ISSET(resp.fd, &info_pending)) {
    /* Duplicate or spoof. Ignore. */
    return;
  }

  FD_CLR(resp.fd, &info_pending);

  /* See if we have any other pending queries and change state if not. */
  for (n = 0, count = 0; n < pending_max; n++)
    if (FD_ISSET(n, &info_pending))
      count++;

  if (count == 0) {
    info_slave_state = INFO_SLAVE_READY;
    pending_max = 0;
  }

  hp = hostname;
  if (resp.hostname[0])
    safe_str(resp.hostname, hostname, &hp);
  else
    safe_str(resp.ipaddr, hostname, &hp);
  *hp = '\0';

  if (Forbidden_Site(resp.ipaddr) || Forbidden_Site(hostname)) {
    if (!Deny_Silent_Site(resp.ipaddr, AMBIGUOUS)
        || !Deny_Silent_Site(hostname, AMBIGUOUS)) {
      do_log(LT_CONN, 0, 0, "[%d/%s/%s] Refused connection.", resp.fd,
             hostname, resp.ipaddr);
    }
    shutdown(resp.fd, 2);
    closesocket(resp.fd);
    return;
  }

  if (resp.connected_to == TINYPORT)
    source = CS_IP_SOCKET;
  else if (resp.connected_to == SSLPORT)
    source = CS_OPENSSL_SOCKET;
  else
    source = CS_UNKNOWN;

  do_log(LT_CONN, 0, 0, "[%d/%s/%s] Connection opened from %s.", resp.fd,
         hostname, resp.ipaddr, source_to_s(source));
  set_keepalive(resp.fd, options.keepalive_timeout);


  initializesock(resp.fd, hostname, resp.ipaddr, source);
}
コード例 #10
0
ファイル: endpts.c プロジェクト: xtompok/netstream
/* Output endpoint. Gets pointer to endpoint config in args */
void * write_endpt(void * args) {

	struct endpt_cfg * cfg;
	cfg = (struct endpt_cfg *)args;

	// Mask signals
	sigset_t sigset;
	if (sigfillset(&sigset) == -1)
	{
		tdprint(args, WARN, "Error in signal setup\n");
		exit_thread(cfg, -1);
	}
	if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) {
		tdprint(args, WARN, "Error in signal setup\n");
		exit_thread(cfg, -1);
	}

	int writefd = -1;
	do  {
		tdprint(args, INFO, "Start writing\n", args);
		// For use in sendto
		struct sockaddr * addr = NULL;
		socklen_t addrlen = 0;
		if (cfg->type == T_FILE) {
			writefd = open(cfg->name, O_WRONLY | O_CREAT | O_TRUNC,
				S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
			if (writefd == -1) {
				warn("Opening file %s to write failed\n",
					cfg->name);
				cfg->exit_status = -1;
				goto write_repeat;
			}
			if (cfg->test_only) {
				close(writefd);
				exit_thread(cfg, 0);
			}


		} else if (cfg->type == T_SOCKET) {
			struct addrinfo hints;
			memset(&hints, 0, sizeof (struct addrinfo));
			hints.ai_family = AF_UNSPEC;
			if (cfg->protocol == IPPROTO_TCP)
				hints.ai_socktype = SOCK_STREAM;
			else if (cfg->protocol == IPPROTO_UDP)
				hints.ai_socktype = SOCK_DGRAM;
			hints.ai_flags = 0;
			hints.ai_protocol = 0;

			int res;
			struct addrinfo * addrinfo;
			res = getaddrinfo(cfg->name,
				cfg->port,
				&hints,
				&addrinfo);
			if (res) {
				tdprint(args,
					ERR,
					"Error when resolving %s: %s\n",
					cfg->name,
					gai_strerror(res));
				cfg->exit_status = -1;
				goto write_repeat;
			}
			for (struct addrinfo * aiptr = addrinfo;
				aiptr != NULL;
				aiptr = aiptr->ai_next) {

				addr = aiptr->ai_addr;
				addrlen = aiptr->ai_addrlen;
				writefd = socket(aiptr->ai_family,
					aiptr->ai_socktype,
					aiptr->ai_protocol);
				if (writefd == -1)
					continue;
				if (cfg->protocol == IPPROTO_UDP)
					break;
				if (cfg->keepalive != 0) {
					set_keepalive(writefd,
						args,
						cfg->keepalive);
				}
				if (connect(writefd, addr, addrlen) != -1)
					break;
				close(writefd);
				writefd = -1;
			}
			freeaddrinfo(addrinfo);
			if (writefd == -1) {
				tdprint(args,
					ERR,
					"Could not connect to %s\n",
					cfg->name);
				cfg->exit_status = -1;
				goto write_repeat;
			}
			if (cfg->test_only) {
				close(writefd);
				exit_thread(cfg, 0);
			}

		} else if (cfg->type == T_STD) {
			writefd = 1;
			if (cfg->test_only) {
				exit_thread(cfg, 0);
			}
		}

		char * writebuf;
		while (1)  {
			size_t towrite;
			towrite = buffer_after_delete(cfg->buf);
			if (towrite == BUF_END_DATA) {
				cfg->exit_status = 0;
				tdprint(args, INFO, "End of data\n", args);
				close(writefd);
				exit_thread(cfg, cfg->exit_status);
			}
			if (towrite == BUF_KILL) {
				cfg->exit_status = -2;
				tdprint(args,
					INFO,
					"End required by signal\n",
					args);
				close(writefd);
				exit_thread(cfg, cfg->exit_status);
			}
			writebuf = buffer_cons_data_pointer(cfg->buf);
			if (cfg->type == T_SOCKET &&
				cfg->protocol == IPPROTO_UDP) {

				ssize_t res;
				res = sendto(writefd,
					writebuf,
					towrite,
					0,
					addr,
					addrlen);
				if (res == -1)
					warn("Error in sending data\n");
			} else  {
				int nwritten;
				nwritten = 0;
				while (nwritten < towrite) {
					ssize_t res;
					res = write(writefd,
						(void *)(writebuf+nwritten),
						towrite-nwritten);
					if (res < 0) {
						warn("Error in sending data");
						cfg->exit_status = -1;
						close(writefd);
						goto write_repeat;
					}
					nwritten += res;
				}
			}
		}
	write_repeat:
		switch (cfg->retry) {
			case YES:
				tdprint(args, INFO, "Retrying\n", args);
				break;
			case NO:
				tdprint(args, INFO, "Terminating\n", args);
				exit_thread(cfg, cfg->exit_status);
			case IGNORE:
			case KILL:
				tdprint(args, INFO, "Terminating\n", args);
				exit_thread(cfg, 0);
		}
		sleep(RETRY_DELAY);

	} while (1);

	// Unreachable
	exit_thread(cfg, cfg->exit_status);
}
コード例 #11
0
ファイル: endpts.c プロジェクト: xtompok/netstream
/* Endpoint for input. Gets pointer to I/O config in args */
void * read_endpt(void * args) {
	struct io_cfg * cfg;
	cfg = (struct io_cfg *) args;
	struct endpt_cfg * read_cfg;
	read_cfg = cfg->input;
	read_cfg->exit_status = 0;

	// Mask signals
	sigset_t sigset;
	if (sigfillset(&sigset) == -1)
	{
		tdprint((void *)read_cfg, WARN, "Error in signal setup\n");
		exit_thread(read_cfg, -1);
	}
	if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) {
		tdprint((void *)read_cfg, WARN, "Error in signal setup\n");
		exit_thread(read_cfg, -1);
	}


	int listenfd;
	listenfd = -1;
	int readfd;
	readfd = -1;
	do  {
		tdprint((void *)read_cfg, INFO, "Start reading\n");
		if (read_cfg->type == T_FILE) {
			tdprint((void *)read_cfg, DEBUG, "File\n");
			readfd = open(read_cfg->name, O_RDONLY);
			if (readfd == -1) {
				warn("Error while opening %s for reading: ",
					read_cfg->name);
				read_cfg->exit_status = -1;
				goto read_repeat;
			} else if (read_cfg->test_only) {
				close(readfd);
				exit_thread(read_cfg, 0);
			}
		} else if (read_cfg->type == T_SOCKET &&
			read_cfg->protocol == IPPROTO_TCP) {

			tdprint((void *)read_cfg, DEBUG, "Socket\n");
			if (listenfd == -1) {
				struct addrinfo hints;
				memset(&hints, 0, sizeof (struct addrinfo));
				hints.ai_family = AF_UNSPEC;
				hints.ai_socktype = SOCK_STREAM;
				hints.ai_flags = AI_PASSIVE;
				hints.ai_protocol = 0;

				int res;
				struct addrinfo * addrinfo;
				res = getaddrinfo(NULL,
					read_cfg->port,
					&hints,
					&addrinfo);
				if (res) {
					tdprint((void *)read_cfg,
						ERR,
						"Error when resolving %s: %s\n",
						read_cfg->name,
						gai_strerror(res));
					read_cfg->exit_status = -1;
					goto read_repeat;
				}
				for (struct addrinfo * aiptr = addrinfo;
					aiptr != NULL;
					aiptr = aiptr->ai_next) {

					listenfd = socket(aiptr->ai_family,
						aiptr->ai_socktype,
						aiptr->ai_protocol);
					if (listenfd == -1)
						continue;
					tdprint((void *)read_cfg,
						DEBUG,
						"Binding\n");
					if (bind(listenfd, aiptr->ai_addr,
						aiptr->ai_addrlen) == 0)

						break;
					close(listenfd);
					listenfd = -1;
				}
				freeaddrinfo(addrinfo);
				if (listenfd == -1) {
					tdprint((void *)read_cfg,
						ERR,
						"Could not bind to port %s\n",
						read_cfg->port);
					read_cfg->exit_status = -1;
					goto read_repeat;
				}
				tdprint((void *)read_cfg, DEBUG, "Listening\n");
				if (listen(listenfd, 1)) {
					warn("Could not listen on port %s\n",
						read_cfg->port);
					read_cfg->exit_status = -1;
					goto read_repeat;
				}
			}

			if (read_cfg->test_only) {
				close(listenfd);
				exit_thread(read_cfg, 0);
			}

			tdprint((void *)read_cfg, DEBUG, "Accepting\n");
			int res = wait_for_event((void *) read_cfg,
				"accept",
				listenfd,
				signal_fds[0]);
			switch (res) {
				case WFE_POLL_ERR:
					close(listenfd);
					listenfd = -1;
					read_cfg->exit_status = -1;
					goto read_repeat;
					break;
				case WFE_SIG_TERM:
					read_cfg->retry = KILL;
					goto read_repeat;
					break;
				case WFE_EVT:
					break;
			}
			readfd = accept(listenfd, NULL, NULL);
			if (readfd == -1) {
				warn("Could not accept on port %s:",
					read_cfg->port);
				read_cfg->exit_status = -1;
				goto read_repeat;
			}
			if (read_cfg->keepalive != 0) {
				set_keepalive(readfd,
					read_cfg,
					read_cfg->keepalive);
			}
			tdprint((void *)read_cfg, DEBUG, "Reading\n");

		} else if (read_cfg->type == T_SOCKET &&
			read_cfg->protocol == IPPROTO_UDP) {

			tdprint((void *)read_cfg, DEBUG, "Socket\n");
			struct addrinfo hints;
			memset(&hints, 0, sizeof (struct addrinfo));
			hints.ai_family = AF_UNSPEC;
			hints.ai_socktype = SOCK_DGRAM;
			hints.ai_flags = AI_PASSIVE;
			hints.ai_protocol = 0;

			int res;
			struct addrinfo * addrinfo;
			res = getaddrinfo(NULL,
				read_cfg->port,
				&hints,
				&addrinfo);
			if (res) {
				tdprint((void *)read_cfg,
					ERR,
					"Error when resolving %s: %s\n",
					read_cfg->name,
					gai_strerror(res));
				read_cfg->exit_status = -1;
				goto read_repeat;
			}
			for (struct addrinfo * aiptr = addrinfo;
				aiptr != NULL;
				aiptr = aiptr->ai_next) {

				readfd = socket(aiptr->ai_family,
					aiptr->ai_socktype,
					aiptr->ai_protocol);
				if (readfd == -1)
					continue;
				tdprint((void *)read_cfg, DEBUG, "Binding\n");
				if (bind(readfd,
					aiptr->ai_addr,
					aiptr->ai_addrlen) == 0)

					break;
				close(readfd);
			}
			freeaddrinfo(addrinfo);
			if (readfd == -1) {
				tdprint((void *)read_cfg,
					ERR,
					"Could not bind to port %s\n",
					read_cfg->port);
				read_cfg->exit_status = -1;
				goto read_repeat;
			}
			tdprint((void *)read_cfg, DEBUG, "Reading\n");

			if (read_cfg->test_only) {
				close(readfd);
				exit_thread(read_cfg, 0);
			}

		} else if (read_cfg->type == T_STD) {
			tdprint((void *)read_cfg, DEBUG, "Stdin\n");
			readfd = 0;
			if (read_cfg->test_only) {
				exit_thread(read_cfg, 0);
			}

		}

		char * readbuf;
		readbuf = malloc(sizeof (char)*READ_BUFFER_BLOCK_SIZE);
		while (1) {
			tdprint((void *)read_cfg, DEBUG, "Rereading\n");
			size_t toread;
			size_t nread;
			toread = READ_BUFFER_BLOCK_SIZE;
			nread = 0;
			while (nread < toread) {
				int res = wait_for_event((void *) read_cfg,
					"read",
					readfd,
					signal_fds[0]);
				switch (res) {
					case WFE_POLL_ERR:
						close(readfd);
						free(readbuf);
						read_cfg->exit_status = -1;
						goto read_repeat;
						break;
					case WFE_SIG_TERM:
						read_cfg->retry = KILL;
						goto read_repeat;
						break;
					case WFE_EVT:
						break;
				}

				if (read_cfg->type == T_SOCKET &&
					read_cfg->protocol == IPPROTO_UDP) {

					struct sockaddr from_addr;
					socklen_t from_addrlen;
					// From sys/socket.h, does
					// exist more correct system?
					from_addrlen = 14;
					res = recvfrom(readfd,
						(void *)readbuf,
						READ_BUFFER_BLOCK_SIZE,
						0,
						&from_addr,
						&from_addrlen);

					tdprint((void *)read_cfg,
						INFO,
						"Got message from socket\n");

				} else  {
					res = read(readfd,
						(void *)(readbuf+nread),
						(toread-nread));
				}
				if (res == 0) { // EOF
					close(readfd);
					for (int i = 0; i < cfg->n_outs; i++) {
						buffer_insert(cfg->outs[i].buf,
							readbuf,
							nread);
					}
					free(readbuf);
					read_cfg->exit_status = 0;
					goto read_repeat;
				} else if (res == -1) { // Error
					warn("Error while reading from %s",
						read_cfg->name);
					close(readfd);
					free(readbuf);
					read_cfg->exit_status = -1;
					goto read_repeat;
				}
				nread += res;
				if (read_cfg->type == T_SOCKET &&
					read_cfg->protocol == IPPROTO_UDP) {
					break;
				}
			}
			for (int i = 0; i < cfg->n_outs; i++) {
				buffer_insert(cfg->outs[i].buf, readbuf, nread);
			}
		}
	read_repeat:
		if (read_cfg->test_only) {
			exit_thread(read_cfg, read_cfg->exit_status);
		}
		switch (read_cfg->retry) {
			case YES:
				tdprint((void *)read_cfg,
					INFO,
					"Retrying read\n");
				break;
			case KILL:
				close(listenfd);
				tdprint((void *)read_cfg,
					INFO,
					"Ending read\n");
				for (int i = 0; i < cfg->n_outs; i++) {
					buffer_insert(cfg->outs[i].buf,
						NULL,
						BUF_KILL);
				}
				exit_thread(read_cfg, -2);
			case NO:
			case IGNORE:
				close(listenfd);
				tdprint((void *)read_cfg,
					INFO,
					"Ending read\n");
				for (int i = 0; i < cfg->n_outs; i++) {
					buffer_insert(cfg->outs[i].buf,
						NULL,
						BUF_END_DATA);
				}
				exit_thread(read_cfg, read_cfg->exit_status);

		}
		sleep(RETRY_DELAY);
	} while (1);
	// Should be unreachable
	exit_thread(read_cfg, read_cfg->exit_status);
}
コード例 #12
0
int main(int argc, char **argv)
{
	if(argc<2)
	{
		fprintf(stderr,"Usage:\n %s <port>\n",argv[0]);
		return 1;
	}
    int serverPort =atoi(argv[1]);
	if(serverPort<1)
	{
		fprintf(stderr,"serverPort{%d} error\n",serverPort);
		return 1;
	}
    
    struct epoll_event ev;
    struct epoll_event events[MAXEPOLLSIZE];
    
    int listenerfd = socket(PF_INET, SOCK_STREAM, 0);
    if (-1==listenerfd)
    {
        printf("ERROR socket ,errno=%d,rt=%d,%s \n",errno,listenerfd,strerror(errno));
        return 0;
    }

	int opt=SO_REUSEADDR;
    setsockopt(listenerfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));	
    setnonblocking(listenerfd);
    
    struct sockaddr_in my_addr;
    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = PF_INET;
    my_addr.sin_port = htons(serverPort);
    my_addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(listenerfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1) 
    {
        printf("ERROR bind ,errno=%d,%s \n",errno,strerror(errno));
        return 0;
    } 
    if (listen(listenerfd, 128) == -1) 
    {
        printf("ERROR listen ,errno=%d,%s \n",errno,strerror(errno));
        return 0;
    }

    int efd = epoll_create(MAXEPOLLSIZE);
    socklen_t len = sizeof(struct sockaddr_in);
    ev.events = EPOLLIN | EPOLLET;
    ev.data.fd = listenerfd;
    if (epoll_ctl(efd, EPOLL_CTL_ADD, listenerfd, &ev) < 0) 
    {
        printf("ERROR epoll_ctl ,errno=%d,%s \n",errno,strerror(errno));
        return 0;
    }
    
    int maxevents = 1;
    while (maxevents>0) 
    {
        int n = epoll_wait(efd, events, maxevents, -1);
		printf("      epoll_wait returned %d \n",n);
        if (n == -1)
        {
            printf("ERROR epoll_wait ,errno=%d,%s \n",errno,strerror(errno));
            return 0;
        }
     
        for (int i = 0; i < n; ++i)
        {
            if (events[i].data.fd == listenerfd) 
            {
                struct sockaddr_in their_addr;
                int clientfd = accept(listenerfd, (struct sockaddr *) &their_addr,&len);
                if (clientfd < 0) 
                {
                    printf("ERROR accept ,errno=%d,%s \n",errno,strerror(errno));
                    continue;
                } 
                else
                {
                    printf("     Connected from %s:%d, client socket:%d\n",
                            inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), clientfd);
                }
                setnonblocking(clientfd);
                
                if(0!=set_keepalive(clientfd))
                {
                    printf("ERROR set_keepalive ,errno=%d,%s \n",errno,strerror(errno));
                    continue;
                }
                if(0!=set_tcp_user_timeout(clientfd))
                {
                    printf("ERROR set_tcp_user_timeout ,errno=%d,%s \n",errno,strerror(errno));
                    continue;
                }
                
                ev.events = EPOLLIN | EPOLLET;
                ev.data.fd = clientfd;
                if (epoll_ctl(efd, EPOLL_CTL_ADD, clientfd, &ev) < 0)
                {
                    printf("ERROR epoll_ctl ,errno=%d,%s \n",errno,strerror(errno));
                    return -1;
                }
                maxevents++;
            } 
            else
            {
                int rt = handle_message(events[i].data.fd);
                if (rt < 1 && errno != 11)
                {
                    epoll_ctl(efd, EPOLL_CTL_DEL, events[i].data.fd,&ev);
                    maxevents--;
                }
            }
        }
    }
    close(listenerfd);
    return 0;
}
コード例 #13
0
ファイル: main.c プロジェクト: EmisFR/burp
static int init_listen_socket(const char *address, const char *port, int *fds)
{
	int i;
	int gai_ret;
	struct addrinfo hints;
	struct addrinfo *rp=NULL;
	struct addrinfo *info=NULL;

	close_fds(fds);

	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family=AF_UNSPEC;
	hints.ai_socktype=SOCK_STREAM;
	hints.ai_protocol=IPPROTO_TCP;
	hints.ai_flags=AI_NUMERICHOST;
	hints.ai_flags|=AI_PASSIVE;

	if((gai_ret=getaddrinfo(address, port, &hints, &info)))
	{
		logp("unable to getaddrinfo on port %s: %s\n",
			port, gai_strerror(gai_ret));
		return -1;
	}

	i=0;
	for(rp=info; rp && i<LISTEN_SOCKETS; rp=rp->ai_next)
	{
		fds[i]=socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
		if(fds[i]<0)
		{
			logp("unable to create socket on port %s: %s\n",
				port, strerror(errno));
			continue;
		}
		set_keepalive(fds[i], 1);
#ifdef HAVE_IPV6
		if(rp->ai_family==AF_INET6)
		{
			// Attempt to say that it should not listen on IPv6
			// only.
			int optval=0;
			setsockopt(fds[i], IPPROTO_IPV6, IPV6_V6ONLY,
				&optval, sizeof(optval));
		}
#endif
		reuseaddr(fds[i]);
		if(bind(fds[i], rp->ai_addr, rp->ai_addrlen))
		{
			logp("unable to bind socket on port %s: %s\n",
				port, strerror(errno));
			close(fds[i]);
			fds[i]=-1;
			continue;
		}

		// Say that we are happy to accept connections.
		if(listen(fds[i], 5)<0)
		{
			close_fd(&(fds[i]));
			logp("could not listen on main socket %s\n", port);
			return -1;
		}

#ifdef HAVE_WIN32
		{
			u_long ioctlArg=0;
			ioctlsocket(fds[i], FIONBIO, &ioctlArg);
		}
#endif
		i++;
	}

	freeaddrinfo(info);

	if(!i)
	{
		logp("could not listen on address: %s\n", address);
#ifdef HAVE_IPV6
		if(strchr(address, ':'))
			logp("maybe check whether your OS has IPv6 enabled.\n");
#endif
		return -1;
	}

	return 0;
}