Пример #1
0
Interface* discoverInterfaces(Config *config, bool shouldBind) {
	struct ifi_info	*ifi, *ifihead;
	struct sockaddr	*sa;
	bool insert = false;
	int server_fd = 0;
	// Create memory for the list.
	Interface *list = NULL;
	// Use crazy code to loop through the interfaces
	for (ifihead = ifi = Get_ifi_info_plus(AF_INET, 1); ifi != NULL; ifi = ifi->ifi_next) {
		// Create node
		Interface *node = malloc(sizeof(Interface));
		insert = false;
		// Null out pointers
		node->next = NULL;
		node->prev = NULL;
		// Copy the name of the interface
		strcpy(node->name, ifi->ifi_name); 
		// Copy the IPAddress
		if((sa = ifi->ifi_addr) != NULL) {
			strcpy(node->ip_address, Sock_ntop_host(sa, sizeof(*sa)));
		}
		// Copy the network mask
		if((sa = ifi->ifi_ntmaddr) != NULL) {
			strcpy(node->network_mask, Sock_ntop_host(sa, sizeof(*sa)));
		}
		// Print out info
		info("<%s> [%s%s%s%s%s\b] IP: %s Mask: %s\n", 
			node->name,
			ifi->ifi_flags & IFF_UP ? "UP " : "",
			ifi->ifi_flags & IFF_BROADCAST ? "BCAST " : "",
			ifi->ifi_flags & IFF_MULTICAST ? "MCAST " : "",
			ifi->ifi_flags & IFF_LOOPBACK ? "LOOP " : "",
			ifi->ifi_flags & IFF_POINTOPOINT ? "P2P " : "",
			node->ip_address,
			node->network_mask);

		if(shouldBind) {
			/* Config was successfully parsed; attempt to bind sockets */
			server_fd = createServer(node->ip_address, config->port);
			if(server_fd != SERVER_SOCKET_BIND_FAIL) {
				node->sockfd = server_fd;
				insert = true;
			} else {
				/* Unable to bind socket to port */
				fprintf(stderr, "Failed to bind socket: %s:%u\n", node->ip_address, config->port);
			}
		} else {
			insert = true;
		}

		// If all was successful insert into the list
		if(insert) {
			if(list == NULL) {
				list = node;	
			} else {
				// Just push it down the list
				// IE: It goes in reverse discovery order
				node->next = list;
				list->prev = node;
				list = node;
			}
		}
	}
	free_ifi_info_plus(ifihead);
	return list;
}
Пример #2
0
int main(int argc, char** argv) {
    struct datagram conn_gram;
    struct ifi_info *ifihead, *ifi;
    struct sockaddr_in servaddr;
    struct sockaddr_in cliaddr;
    fd_set rset, allset;
    socklen_t len;
    ssize_t n;
    int nready;
    int on = 1;
    int maxfdp1 = 0;
    int i;
    int send_flag;
    pid_t pid;

    ifihead = get_ifi_head();
    printf("Server IP Addresses:\n");
    print_ifi_info(ifihead);

    readfile();

    printf("Listening port %d\n", port);

    count = 0;
    for (ifi=ifihead;ifi!=NULL;ifi=ifi->ifi_next) {
	if (!(ifi->ifi_flags & IFF_UP))
		continue;

        addrs[count] = ifi;
        sockfds[count] = Socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfds[count] > maxfdp1)
            maxfdp1 = sockfds[count];

        Setsockopt(sockfds[count], SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
        memcpy(&servaddr, ifi->ifi_addr, sizeof(servaddr));
        servaddr.sin_port = htons(port);
        Bind(sockfds[count], (SA *) &servaddr, sizeof(servaddr));

        count++;
        if (count >= MAX_IFI_COUNT)
            break;
    }

    FD_ZERO(&allset);
    FD_ZERO(&rset);
    for (i=0;i<count;i++) {
        FD_SET(sockfds[i], &allset);
    }
    maxfdp1 = maxfdp1+1;

    signal(SIGCHLD, sigchld);
    for(;;) {
        rset = allset;
        if ((nready = select(maxfdp1, &rset, NULL, NULL, NULL)) < 0) {
            if (errno == EINTR)
                continue;
            else
                err_sys("select error");
        }

        for (i=0;i<count;i++) {
            if (FD_ISSET(sockfds[i], &rset)) {
                len = sizeof(cliaddr);
                n = recv_from(sockfds[i], &conn_gram, &cliaddr, &len);
                send_flag = get_flag(&conn_gram);
                if (!n || (send_flag & RETRY)) {
                    // client timeout, don't fork new child
                    continue;
                }

                printf("Client [%s:%d] connected\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

                pid = fork();
                if (!pid) {
                    child(i, &cliaddr, &conn_gram);
                    // exit
                    return 0;
                }
            }
        }
    }

    free_ifi_info_plus(ifihead);

    return 0;
}