/*
 * Get a UDP socket, bind it, figure out the port,
 * and advertise the port as program "prog".
 *
 * XXX - it would be nice if you could advertise ascii strings.
 */
int
udp_server(u_long prog, int rdwr)
{
	int	sock;
	struct	sockaddr_in s;

	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		perror("socket");
		exit(1);
	}
	sock_optimize(sock, rdwr);
	bzero((void*)&s, sizeof(s));
	s.sin_family = AF_INET;
#ifdef	NO_PORTMAPPER
	s.sin_port = htons(prog);
#endif
	if (bind(sock, (struct sockaddr*)&s, sizeof(s)) < 0) {
		perror("bind");
		exit(2);
	}
#ifdef PORTMAP
	(void)pmap_unset(prog, (u_long)1);
	if (!pmap_set(prog, (u_long)1, (u_long)IPPROTO_UDP,
	    (unsigned short)sockport(sock))) {
		perror("pmap_set");
		exit(5);
	}
#endif
	return (sock);
}
Esempio n. 2
0
/*
 * Accept a connection and return it
 */
int
tcp_accept(int sock, int rdwr)
{
    struct sockaddr_in 	s;
    int 				newsock;
    socklen_t			namelen;

    namelen = sizeof(s);
    bzero((void*)&s, namelen);

retry:
    if ((newsock = accept(sock, (struct sockaddr*)&s, &namelen)) < 0) {
        if (errno == EINTR)
            goto retry;
        perror("accept");
        exit(6);
    }
#ifdef  LIBTCP_VERBOSE
    fprintf(stderr, "Server newsock port %d\n", sockport(newsock));
#endif
    sock_optimize(newsock, rdwr);
    return (newsock);
}
Esempio n. 3
0
// NOTE: this function can create multiple listen sockets, but will only return the last one!
listen_socket * new_listen_socket(uint16_t listen_port, uint8_t protocol) {
	struct addrinfo hints;
	struct addrinfo *result, *rp;
	int s;
	char service[7];
	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;
	hints.ai_canonname = NULL;
	hints.ai_addr = NULL;
	hints.ai_next = NULL;

	snprintf(service, 7, "%d", listen_port);
	if ((s = getaddrinfo(NULL, service, &hints, &result)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
		exit(1);
	}

	listen_socket *listensock;
	for (rp = result; rp != NULL; rp = rp->ai_next) {
		listensock = malloc(sizeof(listen_socket));
		listensock->type = SOCKTYPE_LISTEN;

		memcpy(&listensock->addr, rp->ai_addr, rp->ai_addrlen);

		listensock->fd = socket(rp->ai_family, SOCK_STREAM, IPPROTO_TCP);

		int yes = 1;
		if (setsockopt(listensock->fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
			perror("setsockopt");
			exit(1);
		}

		if (rp->ai_family == AF_INET6) {
			if (setsockopt(listensock->fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(int)) == -1) {
				perror("setsockopt");
				exit(1);
			}
		}

		if (bind(listensock->fd, rp->ai_addr, rp->ai_addrlen) == -1) {
			perror("bind");
			exit(1);
		}

		if (listen(listensock->fd, SOMAXCONN) == -1) {
			perror("listen");
			exit(1);
		}

		sock2a(rp->ai_addr, buf, BUFFER_SIZE);
		fprintf(stderr, "Listening on %s\n", buf);

		listensock->port = sockport(rp->ai_addr);
		listensock->protocol = protocol;

		readsockets = array_push(readsockets, listensock);
		errorsockets = array_push(errorsockets, listensock);
	}

	freeaddrinfo(result);
	return listensock;
}