void startTcpSocket(auto sock_fd, auto addr, auto port) {
    struct sockaddr_in SockAddr;
    SockAddr.sin_family = AF_INET;
    SockAddr.sin_port = port;
    SockAddr.sin_addr.s_addr = addr;

    if (bind(sock_fd, (struct sockaddr *) &SockAddr, sizeof(SockAddr)) == -1)
        throw syscall_error("bind");
    set_nonblock(sock_fd);
    if (listen(sock_fd, SOMAXCONN) == -1)
        throw syscall_error("listen");
}
void set_nonblock(int fd) {
    int flags;
    if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
        flags = 0;
    if (fcntl(fd, F_SETFD, flags | O_NONBLOCK) == -1) {
        throw syscall_error("fcntl");
    }
}
Ejemplo n.º 3
0
std::size_t SocketUtils::sock_fd_read(int sock, void *buf, std::size_t bufsize, int *fd) {
    //File descriptor received
    if (fd) {
        //Declaration
        auto msg = msghdr();
        auto iov = iovec();
        union {
            cmsghdr cmsgheader;
            char control[CMSG_SPACE(sizeof(int))];
        } cmsgu;
        struct cmsghdr *cmsg;

        //Definition
        iov.iov_base = buf;
        iov.iov_len = bufsize;
        msg.msg_name = nullptr;
        msg.msg_namelen = 0;
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
        msg.msg_control = cmsgu.control;
        msg.msg_controllen = sizeof(cmsgu.control);

        //receiving data
        auto size = recvmsg(sock, &msg, 0);
        if (size < 0) throw syscall_error("sock_fd_read: recvmsg");

        //Getting file descriptor
        cmsg = CMSG_FIRSTHDR(&msg);
        if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
            if (cmsg->cmsg_level != SOL_SOCKET) throw syscall_error("Invalid cmsg level");
            if (cmsg->cmsg_type != SCM_RIGHTS) throw syscall_error("Invalid cmsg rights");
            *fd = *((int *) CMSG_DATA(cmsg));
            printf("recieved fd %d\n", *fd);
        } else
            *fd = -1;

        return static_cast<size_t>(size);
    }

    //File descriptor is not received
    auto size = read(sock, buf, bufsize);
    if (size < 0) throw syscall_error("sock_fd_read: read");
    return static_cast<size_t>(size);
}
void polling(auto MasterSocket) {
    static const int POLL_SIZE = 2048;
    std::array<pollfd, 2048> read_set{};
    read_set[0].fd = MasterSocket;
    read_set[0].events = POLLIN;
    int read_set_size = 1;

    while (true) {
        std::cout << std::endl;
        if (poll(read_set.data(), static_cast<nfds_t >(read_set_size), -1) == -1)
            throw syscall_error("poll");
        auto tmp_size = read_set_size;
        for (auto it = read_set.cbegin(); it != read_set.cbegin() + tmp_size; it++) {
            if (it->revents & POLLIN) {
                // new connection
                if (it == read_set.cbegin()) {
                    auto SlaveSocket = accept(MasterSocket, nullptr, 0);
                    if (SlaveSocket == -1) throw syscall_error("accept");
                    set_nonblock(SlaveSocket);
                    read_set[read_set_size].fd = SlaveSocket;
                    read_set[read_set_size].events = POLLIN;
                    read_set_size++;
                } // New data
                else {
                    char buffer[50];
                    auto nread = recv(it->fd, buffer, sizeof(buffer), MSG_NOSIGNAL);
                    if (nread == -1) throw syscall_error("recv");
                    if (nread == 0 && errno != EAGAIN) {
                        shutdown(it->fd, SHUT_RDWR);
                        close(it->fd);
                        std::remove_if(read_set.begin(), read_set.begin() + read_set_size, [&it](pollfd &item) {
                            return item.fd == it->fd;
                        });
                        read_set[--read_set_size].fd = 0;
                    } else {
                        buffer[nread] = '\0';
                        if (send(it->fd, buffer, static_cast<size_t>(nread + 1), MSG_NOSIGNAL) == -1)
                            throw syscall_error("send");
                    }
                }
            }
        }
    }
}
void selecting(auto MasterSocket) {
    std::set<decltype(MasterSocket), std::greater<decltype(MasterSocket)>> Sockets;
    Sockets.insert(MasterSocket);
    fd_set read_set, tmp;
    FD_ZERO(&read_set);
    FD_SET(MasterSocket, &read_set);

    while (true) {
        tmp = read_set;
        if (select(*Sockets.cbegin() + 1, &tmp, nullptr, nullptr, nullptr) == -1)
            throw syscall_error("select");

        for (auto sock : Sockets) {
            if (FD_ISSET(sock, &tmp)) {
                //New connection
                if (sock == MasterSocket) {
                    decltype(MasterSocket) newSocket;
                    if ((newSocket = accept(sock, nullptr, 0)) == -1)
                        throw syscall_error("accept");
                    FD_SET(newSocket, &read_set);
                    Sockets.insert(newSocket);
                } //New data
                else {
                    char buffer[50];
                    auto nread = recv(sock, buffer, sizeof(buffer), MSG_NOSIGNAL);
                    if (nread == -1) throw syscall_error("recv");
                    if (nread == 0 && errno != EAGAIN) {
                        FD_CLR(sock, &read_set);
                        shutdown(sock, SHUT_RDWR);
                        close(sock);
                        Sockets.erase(sock);
                    } else {
                        buffer[nread] = '\0';
                        if (send(sock, buffer, static_cast<size_t>(nread + 1), MSG_NOSIGNAL) == -1)
                            throw syscall_error("send");
                    }
                }
            }
        }
    }
    close(MasterSocket);
}
Ejemplo n.º 6
0
std::size_t SocketUtils::sock_fd_write(int sock, void *buf, std::size_t buflen, int fd) {

    //Declaration
    auto msg = msghdr();
    auto iov = iovec();
    union {
        cmsghdr cmsgheader;
        char control[CMSG_SPACE(sizeof(int))];
    } cmsgu;
    struct cmsghdr *cmsg;

    //Definition
    iov.iov_base = buf;
    iov.iov_len = buflen;
    msg.msg_name = nullptr;
    msg.msg_namelen = 0;
    msg.msg_iov = &iov;
    msg.msg_iovlen = 1;

    //Passing file descriptor
    if (fd != -1) {
        msg.msg_control = cmsgu.control;
        msg.msg_controllen = sizeof(cmsgu.control);
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_len = CMSG_LEN(sizeof(int));
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;

        printf("passing fd %d\n", fd);
        *((int *) CMSG_DATA(cmsg)) = fd;
    }
        //Not passing file descriptor
    else {
        msg.msg_control = nullptr;
        msg.msg_controllen = 0;

        printf("not passing fd\n");
    }

    //Sending data
    auto size = sendmsg(sock, &msg, 0);
    if (size < 0) throw syscall_error("sock_fd_write: sendmsg");
    return static_cast<size_t>(size);
}
void epolling(auto MasterSocket) {
    static const int MAX_EVENTS = 32;
    auto EPoll = epoll_create1(0);
    if (EPoll == -1) throw syscall_error("epoll_create1");

    struct epoll_event Event;
    Event.data.fd = MasterSocket;
    Event.events = EPOLLIN;
    if(epoll_ctl(EPoll, EPOLL_CTL_ADD, MasterSocket, &Event) == -1)
        throw syscall_error("epoll_ctl");

    while(true) {
        struct epoll_event Events[MAX_EVENTS];
        auto N = epoll_wait(EPoll, Events, MAX_EVENTS, -1);
        if(N==-1) throw syscall_error("epoll_wait");

        for (auto i = 0; i < N; i++) {
            // New connection
            if (Events[i].data.fd == MasterSocket) {
                auto SlaveSocket = accept(MasterSocket, nullptr, 0);
                if (SlaveSocket == -1) throw syscall_error("accept");
                set_nonblock(SlaveSocket);
                struct epoll_event newEvent;
                newEvent.data.fd = SlaveSocket;
                newEvent.events = EPOLLIN;
                if (epoll_ctl(EPoll, EPOLL_CTL_ADD, SlaveSocket, &newEvent) == -1)
                    throw syscall_error("epoll_ctl");
            } //New data
            else {
                char buffer[50];
                auto nread = recv(Events[i].data.fd, buffer, sizeof(buffer), MSG_NOSIGNAL);
                if (nread == -1) throw syscall_error("recv");
                if (nread == 0 && errno != EAGAIN) {
                    shutdown(Events[i].data.fd, SHUT_RDWR);
                    close(Events[i].data.fd);
                } else {
                    buffer[nread] = '\0';
                    if (send(Events[i].data.fd, buffer, static_cast<size_t>(nread + 1), MSG_NOSIGNAL) == -1)
                        throw syscall_error("send");
                }

            }
        }
    }

}
int main(int argc, char **argv) {
    try {
        auto MasterSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (MasterSocket == -1) {
            throw syscall_error("socket");
        }

        startTcpSocket(MasterSocket, htonl(INADDR_ANY), htons(7777));

//        selecting(MasterSocket);
//        polling(MasterSocket);
        epolling(MasterSocket);

    } catch (std::exception &e) {
        std::cout << e.what() << std::endl;
    }

    return 0;
}
Ejemplo n.º 9
0
/* Open the next extension in a split sequence */
static void open_split(split_t *split)
{
    int fd;
    int splitnum = split->total_bytes / split->max_bytes;
    mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
    char *ext, *fname;
    
    ext = getext(split->format, splitnum);
    asprintf(&fname, "%s.%s", split->name, ext);
    free(ext);

    fd = open(fname, O_WRONLY | O_CREAT, perms);

    if (fd < 0)
        syscall_error(fname);

    split->currfd = fd;
    split->curr_bytes = 0;
    
    free(fname);
}
Ejemplo n.º 10
0
int main(int argc, char **argv)
{
	int sockfd;
	int client_sockfd;
	int portnum;
	int clientlen;
	int bytes_read;
	int bytes_written;
	
	char buffer[BUF_SIZE];
	
	struct sockaddr_in server_addr;		// Contains the inet address of the server
	struct sockaddr_in client_addr;     // Contains the inet address of the client
	
	// Make sure the program was started with enough arguments
	if( argc < 2 ) 
	{
		fprintf(stderr, "ERROR: No port number provided, usage is %s <port>", argv[0]);
		exit( EXIT_FAILURE );
	}
	
	// Get our passed port number
	portnum = atoi( argv[1] );
	
	clientlen = sizeof(client_addr);
	
	// Create a new IPv4 socket using TCP
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	
	if( sockfd < 0 ) 
	{
		syscall_error("ERROR: Failed to open socket");
	}
	
	
	// Clear our struct
	memset(&server_addr, 0, sizeof(server_addr));
	
	// Set up our address
	server_addr.sin_family = AF_INET;		  // Address familly IPv4 (AF_INET6 is IPv6)
	server_addr.sin_port   = htons(portnum);  // Port number, converted to network byte order
	
	server_addr.sin_addr.s_addr = INADDR_ANY; // Since we're a server bind to our own IP
	
	
	// Try and bind our address to our existing socket
	if( bind( sockfd, (struct sockaddr*) &server_addr, sizeof(server_addr)) < 0 )
	{
		syscall_error("ERROR: Failed to bind address to socket");
	}
	
	// Allow us to listen to the socket for connections
	listen( sockfd, MAX_BACKLOG_SIZE );
	
	// Block until we get a connection
	if( (client_sockfd = accept( sockfd, (struct sockaddr*) &client_addr, &clientlen )) < 0 )
	{
		syscall_error("ERROR: Failed to accept client connection");
	}
	
	
	// We now have a client!
	while( client_sockfd ) 
	{
		printf("Incoming connection from %s - Waiting for hello\n", inet_ntoa(client_addr.sin_addr));
		
		// Clear our buffer and read one less byte than our size so we are null terminated
		memset(buffer, 0, sizeof(buffer));
		bytes_read = read( client_sockfd, buffer, BUF_SIZE - 1);
		
		if( bytes_read < 0 ) 
		{
			syscall_error("ERROR: Unable to read from socket");
		}
		
		// We got a message from the client
		printf("Recieved message from client: %s\n", buffer);
		
		if( strncmp(buffer, "HELLO", sizeof(buffer)) == 0) 
		{
			printf("Recieved HELLO from client, responding SUCCESS\n");
			bytes_written = write( client_sockfd, "SUCCESS", strlen("SUCCESS") );
		}
		else
		{
			printf("Unknown response from client, responding FAILURE\n");
			bytes_written = write( client_sockfd, "FAILURE", strlen("FAILURE") );
		}
		
		if( bytes_written < 0 ) 
		{
			error("ERROR: Unable to write to socket");
		}
	
	
		// We're done with this client, close the connection and get a new client
		close(client_sockfd);
		
		if( (client_sockfd = accept( sockfd, (struct sockaddr*) &client_addr, &clientlen )) < 0 )
		{
			syscall_error("ERROR: Failed to accept client connection");
		}
	}
	
	return EXIT_SUCCESS;
}