Exemplo n.º 1
0
static void* do_server_write(void *arg)
{
	struct connection_data *data = (struct connection_data *) arg;

	while (1)
	{
		struct data_chunk *chunk = data_take(data->client_buffer);
		if (chunk == NULL || chunk->data == NULL)
			break;

		int done = 0;
		while (done != chunk->size)
		{
			int writed = write(data->connfd, chunk->data + done, chunk->size - done);
			if (writed <= 0)
				break;

			done += writed;
			printf("L->S writed %d bytes\n", writed);
		}

		data_free_chunk(chunk);
	}

	if (is_shutdown_done(data, SHUTDOWN_READ))
		pthread_exit(NULL);

	printf("Sending SHUTDOWN_READ for connection %d\n", data->connid);
	send_packet(data, TYPE_SHUTDOWN_READ, NULL, 0);

	shutdown(data->connfd, SHUT_WR);
	shutdown_connection(data, SHUTDOWN_READ);

	pthread_exit(NULL);
}
Exemplo n.º 2
0
static void* do_icmp_write(void *arg)
{
	if (arg) {}

	while (1)
	{
		struct data_chunk *chunk = data_take(params->client_buffer);
		if (chunk == NULL)
			break;

		struct connection_data *data = (struct connection_data *) chunk->connection;
		if (chunk->data == NULL)
		{
			data_free_chunk(chunk);

			if (is_shutdown_done(data, SHUTDOWN_WRITE))
				continue;

			printf("Sending SHUTDOWN_WRITE for connection %d\n", data->connid);
			send_packet(data, TYPE_SHUTDOWN_WRITE, NULL, 0);

			shutdown(data->connfd, SHUT_RD);
			shutdown_connection(data, SHUTDOWN_WRITE);

			continue;
		}

		int done = 0;
		while (done < chunk->size)
		{
			int tu_size = chunk->size - done;
			if (chunk->size - done > MAX_TRANSFER_UNIT)
				tu_size = MAX_TRANSFER_UNIT;
				
			printf("L->I writed %d bytes\n", tu_size);

			send_packet(data, TYPE_DATA, chunk->data + done, tu_size);
			done += MAX_TRANSFER_UNIT;
		}

		data_free_chunk(chunk);
	}

	pthread_exit(NULL);
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
    // Validate Args.
    if (argc > 3)
    {
        printf("Incorrect num of args. Usage: http_client [Optaion: host_name] [Optional: port]\n");
        exit(EXIT_FAILURE);
    }

    // Default arg values.
    char* host_name = "localhost";
    char* port = "6444";

    if(argc>1){
        host_name = argv[1];
    }

    if (argc > 2 ) {
        port = argv[2];
    }

    // Create Socket.
    int conn_fd = 0;

    // Connect to server.
    if (-1 == connect_to_server(&conn_fd, host_name, port)) {
        close(conn_fd);
        return -1;
    }

    int ret = -1;
    if (0 == Play(conn_fd)) {
        // Shutdown properly the connection.
        ret = shutdown_connection(conn_fd);
    }

    close(conn_fd);

    return ret;
}
Exemplo n.º 4
0
static int32
connection_runner(void *_cookie)
{
	connection_cookie *cookie = (connection_cookie *)_cookie;
	bool run = true;
	commands_info *ci;

	while (run) {
		net_area_info area[MAX_NET_AREAS];
		net_command *command;
		status_t status = B_OK;
		struct stack_driver_args *args;
		int32 index;
		ssize_t bytes = read_port(cookie->localPort,&index,NULL,0);
		if (bytes < B_OK)
			break;

		if (index >= NUM_COMMANDS || index < 0) {
			printf("got bad command index: %lx\n",index);
			continue;
		}
		command = cookie->commands + index;
		if (clone_command_areas(area, command) < B_OK) {
			printf("could not clone command areas!\n");
			continue;
		}
		
		
		ci = g_commands_info;
		while(ci && ci->op) {
			if (ci->op == command->op)
				break;
			ci++;
		}
		
		args = convert_to_local(&command->area[0],&area[0], command->data);
		printf("command %s (0x%lx) (index = %ld), buffer = %p, length = %ld, result = %ld\n",
			ci->name, command->op, index, args, command->length, command->result);

		switch (command->op) {
			case NET_STACK_OPEN:
				cookie->openFlags = args->u.integer;
				printf("Opening socket connection, mode = %lx!\n", cookie->openFlags);
				break;

			case NET_STACK_CLOSE:
				printf("Closing socket connection...\n");
				run = false;
				break;

			case NET_STACK_SOCKET:
				printf("Creating stack socket... family = %d, type = %d, proto = %d\n",
					args->u.socket.family, args->u.socket.type, args->u.socket.proto);
				status = core->socket_init(&cookie->socket);
				if (status == 0)
					status = core->socket_create(cookie->socket, args->u.socket.family, args->u.socket.type, args->u.socket.proto);
				break;

			case NET_STACK_GETSOCKOPT:
			case NET_STACK_SETSOCKOPT:
				if (command->op == (int32) NET_STACK_GETSOCKOPT) {
					status = core->socket_getsockopt(cookie->socket, args->u.sockopt.level, args->u.sockopt.option, 
						convert_to_local(&command->area[1], &area[1], args->u.sockopt.optval),
						(size_t *) &args->u.sockopt.optlen);
				} else {
					status = core->socket_setsockopt(cookie->socket, args->u.sockopt.level, args->u.sockopt.option, 
						(const void *) convert_to_local(&command->area[1], &area[1], args->u.sockopt.optval),
						args->u.sockopt.optlen);
				}
				break;

			case NET_STACK_CONNECT:
			case NET_STACK_BIND:
			case NET_STACK_GETSOCKNAME:
			case NET_STACK_GETPEERNAME: {
				caddr_t addr = (caddr_t) convert_to_local(&command->area[1], &area[1], args->u.sockaddr.addr);

				switch (command->op) {
					case NET_STACK_CONNECT:
						status = core->socket_connect(cookie->socket, addr, args->u.sockaddr.addrlen);
						break;
					case NET_STACK_BIND:
						status = core->socket_bind(cookie->socket, addr, args->u.sockaddr.addrlen);
						break;
					case NET_STACK_GETSOCKNAME:
						status = core->socket_getsockname(cookie->socket, (struct sockaddr *) addr, &args->u.sockaddr.addrlen);
						break;
					case NET_STACK_GETPEERNAME:
						status = core->socket_getpeername(cookie->socket,(struct sockaddr *) addr, &args->u.sockaddr.addrlen);
						break;
				}
				break;
			}
			case NET_STACK_LISTEN:
				status = core->socket_listen(cookie->socket, args->u.integer);
				break;

			case NET_STACK_GET_COOKIE:
				/* this is needed by accept() call, to be able to pass back
				 * in NET_STACK_ACCEPT opcode the cookie of the filedescriptor to 
				 * use for the new accepted socket
				 */
				*((void **) args) = cookie;
				break;
				
			case NET_STACK_ACCEPT:
			{
				connection_cookie *otherCookie = (connection_cookie *) args->u.accept.cookie;
				status = core->socket_accept(cookie->socket, &otherCookie->socket,
					convert_to_local(&command->area[1], &area[1], args->u.accept.addr),
					&args->u.accept.addrlen);
			}
			case NET_STACK_SEND:
			{
				struct iovec iov;
				int flags = 0;

				iov.iov_base = convert_to_local(&command->area[1], &area[1], args->u.transfer.data);
				iov.iov_len = args->u.transfer.datalen;

				status = core->socket_writev(cookie->socket, &iov, flags);
				break;
			}
			case NET_STACK_RECV:
			{
				struct iovec iov;
				int flags = 0;

				iov.iov_base = convert_to_local(&command->area[1], &area[1], args->u.transfer.data);
				iov.iov_len = args->u.transfer.datalen;

				/* flags gets ignored here... */
				status = core->socket_readv(cookie->socket, &iov, &flags);
				break;
			}
			case NET_STACK_RECVFROM:
			{
				struct msghdr *msg = (struct msghdr *) args;
				int received;

				msg->msg_name = convert_to_local(&command->area[1],&area[1],msg->msg_name);
				msg->msg_iov = convert_to_local(&command->area[2],&area[2],msg->msg_iov);
				msg->msg_control = convert_to_local(&command->area[3],&area[3],msg->msg_control);

				status = core->socket_recv(cookie->socket, msg, (caddr_t)&msg->msg_namelen,&received);
				if (status == 0)
					status = received;

				msg->msg_name = convert_to_foreign(&command->area[1],&area[1],msg->msg_name);
				msg->msg_iov = convert_to_foreign(&command->area[2],&area[2],msg->msg_iov);
				msg->msg_control = convert_to_foreign(&command->area[3],&area[3],msg->msg_control);
				break;
			}
			case NET_STACK_SENDTO:
			{
				struct msghdr *msg = (struct msghdr *) args;
				int sent;

				msg->msg_name = convert_to_local(&command->area[1],&area[1],msg->msg_name);
				msg->msg_iov = convert_to_local(&command->area[2],&area[2],msg->msg_iov);
				msg->msg_control = convert_to_local(&command->area[3],&area[3],msg->msg_control);
	
				status = core->socket_send(cookie->socket,msg,msg->msg_flags,&sent);
				if (status == 0)
					status = sent;

				msg->msg_name = convert_to_foreign(&command->area[1],&area[1],msg->msg_name);
				msg->msg_iov = convert_to_foreign(&command->area[2],&area[2],msg->msg_iov);
				msg->msg_control = convert_to_foreign(&command->area[3],&area[3],msg->msg_control);
				break;
			}

			case NET_STACK_NOTIFY_SOCKET_EVENT:
			{
				struct notify_socket_event_args *nsea = (struct notify_socket_event_args *) args;

				cookie->socket_event_port = nsea->notify_port;
				cookie->notify_cookie = nsea->cookie;
		
				if (cookie->socket_event_port != -1)
					// start notify socket event
					status = core->socket_set_event_callback(cookie->socket, on_socket_event, cookie, 0);
				else
					// stop notify socket event
					status = core->socket_set_event_callback(cookie->socket, NULL, NULL, 0);
				break;
			}

			case NET_STACK_SYSCTL:
			{
				status = core->net_sysctl(convert_to_local(&command->area[1],&area[1], args->u.sysctl.name),
					args->u.sysctl.namelen, convert_to_local(&command->area[2],&area[2],args->u.sysctl.oldp),
					convert_to_local(&command->area[3],&area[3],args->u.sysctl.oldlenp),
					convert_to_local(&command->area[4],&area[4],args->u.sysctl.newp),
					args->u.sysctl.newlen);
				break;
			}
/*
			case NET_STACK_STOP:
				core->stop();
				break;
*/				
			case NET_STACK_CONTROL_NET_MODULE:
				// TODO!
				break;

			case B_SET_BLOCKING_IO:
				cookie->openFlags &= ~O_NONBLOCK;
				break;

			case B_SET_NONBLOCKING_IO:
				cookie->openFlags |= O_NONBLOCK;
				break;

			case OSIOCGIFCONF:
			case SIOCGIFCONF:
			{
				struct ifconf *ifc = (struct ifconf *) args;
				ifc->ifc_buf = convert_to_local(&command->area[1], &area[1], ifc->ifc_buf);

				status = core->socket_ioctl(cookie->socket, command->op, (char *) args);

				ifc->ifc_buf = convert_to_foreign(&command->area[1], &area[1], ifc->ifc_buf);
				break;
			}

			default:
				status = core->socket_ioctl(cookie->socket,command->op, (char *) args);
				break;
		}
		// mark the command as done
		command->result = status;
		command->op = 0;
		delete_cloned_areas(area);

		// notify the command pipeline that we're done with the command
		release_sem(cookie->commandSemaphore);
	}

	cookie->runner = -1;
	shutdown_connection(cookie);

	return 0;
}
Exemplo n.º 5
0
Arquivo: nope.c Projeto: amtjre/nope.c
void select_loop(int listenfd)
{

    /* Common vars */

    char socket_pair_buffer[2];
    int nbytes;

    char remote_ip[INET6_ADDRSTRLEN];

    int fd, fdmax;
    int done = 0;

#ifndef NOPE_MAX_CON_CONS
    FdData fdDataList[MAX_NO_FDS];
#else
    FdData *fdDataList;
    LOG_ERROR_ON_NULL(fdDataList =
                      malloc(sizeof(FdData) * MAX_NO_FDS),
                      "Can't malloc() on fdDataList");
#endif

    struct timeval tv;
    int poll_timeout = POLL_TIMEOUT;
    tv.tv_sec = 0;
    tv.tv_usec = POLL_TIMEOUT * 1000;

    /* keep track of the biggest file descriptor */
    fdmax = listenfd;           /* so far, it's this one */

    for (fd = 0; fd < fdmax; fd++) {
        fdDataList[fd].state = STATE_PRE_REQUEST;
    }
#ifdef NOPE_EPOLL

    int eventfd;
    struct epoll_event event;
    struct epoll_event *events;

    eventfd = epoll_create(1234);       /*Number is ignored */

    if (eventfd == -1) {
        perror("epoll_create");
        return;
    }

    event.data.fd = listenfd;
    event.events = EPOLLIN | EPOLLET;

    if (epoll_ctl(eventfd, EPOLL_CTL_ADD, listenfd, &event)) {
        perror("epoll_ctl");
        return;
    }
#ifdef NOPE_THREADS
    /* Socket Pair */
    event.data.fd = socketpair_fd[1];
    event.events = EPOLLIN | EPOLLET;

    if (epoll_ctl(eventfd, EPOLL_CTL_ADD, socketpair_fd[1], &event)) {
        perror("epoll_ctl_socketpair");
        return;
    }
#endif

    events = calloc(MAX_EVENTS, sizeof event);
    /* Epoll main loop */
    while (1) {

#ifdef NOPE_THREADS
        cleaner_thread();       /*Run the thread clearer */
#endif
        int n, e;
        dbgprintf(KCYN "Waiting for events \n" KNRM);
        n = epoll_wait(eventfd, events, MAX_EVENTS, poll_timeout);
        dbgprintf(KCYN "Detected %d events \n" KNRM, n);
        for (e = 0; e < n; e++) {
            if ((events[e].events & EPOLLERR) ||
                (events[e].events & EPOLLHUP) || (!(events[e].events & EPOLLIN))) {
                fprintf(stderr, "epoll error detected in line %d\n", __LINE__);
                close(events[e].data.fd);
                continue;
            }

            else if (listenfd == events[e].data.fd) {
                while (1) {
                    struct sockaddr in_addr;
                    socklen_t in_len;
                    int newfd;
                    char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];

                    in_len = sizeof in_addr;

                    newfd = accept(listenfd, &in_addr, &in_len);

                    if (newfd == -1) {
                        if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
                            /* We have processed all incoming  connections. */
                            break;
                        } else {
                            perror("accept");
                            break;
                        }
                    } else if (newfd >= MAX_NO_FDS) {
                        /* Process some events before accepting more */
                        fprintf(stderr, "Reached MAX_NO_FDS at %d\n", newfd);
                        break;
                    }

                    if (getnameinfo(&in_addr, in_len,
                                    hbuf, sizeof hbuf,
                                    sbuf, sizeof sbuf,
                                    NI_NUMERICHOST | NI_NUMERICSERV) == 0) {

                        /*dbgprintf("accept()ed connection on  %d (host=%s, port=%s)\n",
                           newfd, hbuf, sbuf); */

                        fdDataList[newfd].state = STATE_PRE_REQUEST;
                        new_fd_data(&fdDataList[newfd]);
                    }

                    /* Make the incoming socket non-blocking and add it to the list of fds to monitor. */
                    if (FCNTL_NONBLOCK(newfd) < 0) {
                        perror("fcntl");
                        return;
                    }

                    event.data.fd = newfd;
                    event.events = EPOLLIN | EPOLLET;
                    if (epoll_ctl(eventfd, EPOLL_CTL_ADD, newfd, &event) < 0) {
                        perror("epoll_ctl");
                        return;
                    }
                }
                continue;
            }
#ifdef 	NOPE_THREADS
            else if (socketpair_fd[1] == events[e].data.fd) {
                nbytes = read(events[e].data.fd, socket_pair_buffer, 1);
                dbgprintf(KCYN "SocketPair Read %d : %d\n" KCYN, events[e].data.fd,
                          nbytes);
                if (nbytes == -1) {
                    if (errno != EAGAIN) {      /* EAGAINs we have read all data */
                        perror("read");
                    }
                }
            }
#endif
            else {
                fd = events[e].data.fd;
                while (1) {
                    nbytes =
                        read(fd, fdDataList[fd].readBuffer + fdDataList[fd].readBufferIdx,
                             MAX_REQUEST_SIZE - fdDataList[fd].readBufferLen);
                    dbgprintf(KCYN "Read %d : %d\n" KCYN, fd, nbytes);
                    if (nbytes == -1) {
                        if (errno != EAGAIN) {  /* EAGAINs we have read all data */
                            perror("read");
                            done = true;
                        }
                        break;
                    } else if (nbytes == 0) {
                        done = true;
                        break;
                    }
                    if ((done = state_machine(fdDataList, fd, nbytes, NULL))) {
                        break;
                    }
                }

                if (done) {
                    clear_connection_baggage(fdDataList, fd, NULL);
                }

            }
        }
    }
#else
    /* Select stuff
     * Thank you Brian "Beej Jorgensen" Hall */
    fd_set master;              // pMaster file descriptor list
    fd_set read_fds;            // temp file descriptor list for select()

    FD_ZERO(&master);           /* clear the pMaster and temp sets */
    FD_ZERO(&read_fds);

    /* add the listener to the master set */
    FD_SET(listenfd, &master);

    /* Select main loop */
    while (1) {

#ifdef NOPE_THREADS
        cleaner_thread();       /*Run the thread clearer */
#endif

        read_fds = master;      /* copy it */

        dbgprintf(KRED "Select blocking\n" KNRM);
        if (select(fdmax + 1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("select");
            exit(4);
        }
        dbgprintf(KRED "Select blocked\n" KNRM);
        /* run through the existing connections looking for data to read */
        for (fd = 0; fd <= fdmax; fd++) {
            if (!FD_ISSET(fd, &read_fds))       // we got one!!
                continue;
            if (fd == listenfd) {
                accept_connection(fdDataList, listenfd, remote_ip, &fdmax, &master);
                break;
            }
            nbytes =
                recv(fd, fdDataList[fd].readBuffer + fdDataList[fd].readBufferIdx,
                     MAX_REQUEST_SIZE - fdDataList[fd].readBufferLen, 0);
            /* read failure */
            if (nbytes <= 0) {
                shutdown_connection(fdDataList, fd, nbytes, &master);
                break;
            }

            /* State Machine */
            done = state_machine(fdDataList, fd, nbytes, &master);
            if (done) {
                clear_connection_baggage(fdDataList, fd, &master);
            }
        }                       // END looping through file descriptors
    }                           // END for(;;)--and you thought it would never end!
#endif
    return;
}