void ofxVideoRecorder::close()
{
    if(!bIsInitialized) return;

    //set pipes to non_blocking so we dont get stuck at the final writes
    setNonblocking(audioPipeFd);
    setNonblocking(videoPipeFd);
    
    while(frames.size() > 0 && audioFrames.size() > 0) {
        // if there are frames in the queue or the thread is writing, signal them until the work is done.
        videoThread.signal();
        audioThread.signal();
    }
    
    //at this point all data that ffmpeg wants should have been consumed
    // one of the threads may still be trying to write a frame,
    // but once close() gets called they will exit the non_blocking write loop
    // and hopefully close successfully

    bIsInitialized = false;

    if (bRecordVideo) {
        videoThread.close();
    }
    if (bRecordAudio) {
        audioThread.close();
    }

    retirePipeNumber(pipeNumber);

    ffmpegThread.waitForThread();
    // TODO: kill ffmpeg process if its taking too long to close for whatever reason.

}
int EpollSocket::handle_accept_event(int &epollfd, epoll_event &event, EpollSocketWatcher &socket_handler) {
    int sockfd = event.data.fd;

    std::string client_ip;
    int conn_sock = accept_socket(sockfd, client_ip);
    if (conn_sock == -1) {
        return -1;
    }
    setNonblocking(conn_sock);
    LOG_DEBUG("get accept socket which listen fd:%d, conn_sock_fd:%d", sockfd, conn_sock);

    EpollContext *epoll_context = new EpollContext();
    epoll_context->fd = conn_sock;
    epoll_context->client_ip = client_ip;

    socket_handler.on_accept(*epoll_context);

    struct epoll_event conn_sock_ev;
    conn_sock_ev.events = EPOLLIN | EPOLLET;
    conn_sock_ev.data.ptr = epoll_context;

    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &conn_sock_ev) == -1) {
        perror("epoll_ctl: conn_sock");
        exit(EXIT_FAILURE);
    }

    return 0;
}
Beispiel #3
0
int CEpollSocket::handle_accept_event(int epollfd, epoll_event &event, CEpollSocketWatcher &socket_handler) {
    int sockfd = event.data.fd;

    std::string client_ip;
    int conn_sock = accept_socket(sockfd, client_ip);
    if (conn_sock == -1) {
        return -1;
    }
    setNonblocking(conn_sock);
    LOG_DEBUG("get accept socket which listen fd:%d, conn_sock_fd:%d", sockfd, conn_sock);

    CEpollContext *epoll_context = new CEpollContext();
    epoll_context->fd = conn_sock;
    epoll_context->client_ip = client_ip;

    socket_handler.on_accept(*epoll_context);

    struct epoll_event conn_sock_ev;
    conn_sock_ev.events = EPOLLIN;
    conn_sock_ev.data.ptr = epoll_context;

    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &conn_sock_ev) == -1) {
        LOG_ERROR("epoll_ctl: conn_sock:%s", strerror(errno));
        return -1;
    }

    return 0;
}
Beispiel #4
0
/* Try to open a connection to LCDd if support is enabled
** If it succeeeds configure our screen
** If it fails, print a message, disable support and continue
*/
void init_lcd (void)
{
    if (!use_lcdd_menu) return;

    use_lcdd_menu = false;

    lcd_fd = socket(AF_INET, SOCK_STREAM, 0);

    if (lcd_fd > 0)
    {
        lcd_addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in *));
        lcd_addr->sin_family = AF_INET;
        if (inet_pton(AF_INET, "127.0.0.1", (void *)(&(lcd_addr->sin_addr.s_addr))) >0)
        {
            lcd_addr->sin_port = htons(13666);
            if (connect(lcd_fd, (struct sockaddr *)lcd_addr, sizeof(struct sockaddr)) >= 0)
            {
                int flag = 1;
                if (setsockopt(lcd_fd, IPPROTO_TCP, TCP_NODELAY, (void*)&flag, sizeof(flag) ) == 0)
                {
                    use_lcdd_menu = true;
                    send_lcd("hello\n",6);

                    while(!read_lcd());  /* wait for display info */

                    send_lcd("client_set name {squeeze}\n",26);
                    send_lcd("screen_add main\n",16);
                    send_lcd("screen_set main name {main}\n",28);
                    send_lcd("screen_set main heartbeat off\n",30);
                    send_lcd("widget_add main one string\n",27);
                    send_lcd("widget_add main two string\n",27);

                    if ( lcdd_compat )
                        send_lcd("screen_set main -priority 256\n",30);
                    else
                        send_lcd("screen_set main -priority info\n",31);

                    setNonblocking(lcd_fd);
                }
            }
        }
    }

    /* If connect failed */
    if (!use_lcdd_menu)
    {
        use_lcdd_menu = true;
        close_lcd();

        fprintf(stderr,"Connect to LCDd failed!\n");
    }
}
Beispiel #5
0
int bluetooth_open(const char *addr, uint8_t channel, struct gn_statemachine *state)
{
	bdaddr_t bdaddr;
	struct sockaddr_rc raddr;
	int fd;

	if (str2ba((char *)addr, &bdaddr)) {
		fprintf(stderr, _("Invalid bluetooth address \"%s\"\n"), addr);
		return -1;
	}

	if ((fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0) {
		perror(_("Can't create socket"));
		return -1;
	}

	memset(&raddr, 0, sizeof(raddr));
	raddr.rc_family = AF_BLUETOOTH;
	bacpy(&raddr.rc_bdaddr, &bdaddr);
	dprintf("Channel: %d\n", channel);
	if (channel < 1) {
		if (!strcmp(state->config.model, "gnapplet") ||
		    !strcmp(state->config.model, "symbian"))
			channel = get_serial_channel(&bdaddr, 1);
		else
			channel = get_serial_channel(&bdaddr, 0);
	}
	dprintf("Channel: %d\n", channel);

	/* If none channel found, fail. */
	if (channel < 1) {
		fprintf(stderr, _("Cannot find any appropriate rfcomm channel and none was specified in the config.\n"));
		close(fd);
		return -1;
	}

	dprintf("Using channel: %d\n", channel);
	raddr.rc_channel = channel;
	
	if (connect(fd, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) {
		perror(_("Can't connect"));
		close(fd);
		return -1;
	}

	/* Ignore errors. If the socket was not set in the async way,
	 * we can live with that.
	 */
	setNonblocking(fd);

	return fd;
}
Beispiel #6
0
/* Try to open a connection to lircd if suppor is enabled
** if it fails, disable support, print a message and continue
*/
void init_lirc(void) {
    if (using_lirc) {
        using_lirc = false;
        if ((lirc_fd = lirc_init("squeezeslave",1)) > 0) {
            if (lirc_readconfig(lircrc, &lircconfig, NULL)==0) {
                using_lirc = true;
                setNonblocking(lcd_fd);
            } else {
                using_lirc = true;
                close_lirc();
            }
        }
        if (!using_lirc ) fprintf(stderr, "Failed to init LIRC\n");
    }
}
Beispiel #7
0
static int
serverSocket(int af)
{
    int fd, rc;
    if(af == 4) {
        fd = socket(PF_INET, SOCK_STREAM, 0);
    } else if(af == 6) {
#ifdef HAVE_IPv6
        fd = socket(PF_INET6, SOCK_STREAM, 0);
#else
        fd = -1;
        errno = EAFNOSUPPORT;
#endif
    } else {
        abort();
    }

    if(fd >= 0) {
        if(proxyOutgoingAddress != NULL) {
            serverSocket_outgoingIP(fd);
        }

        rc = setNonblocking(fd, 1);
        if(rc < 0) {
            int errno_save = errno;
            CLOSE(fd);
            errno = errno_save;
            return -1;
        }
#ifdef HAVE_IPV6_PREFER_TEMPADDR
        if (af == 6 && useTemporarySourceAddress != 1) {
            int value;
            value = (useTemporarySourceAddress == 2) ? 1 : 0;
            rc = setsockopt(fd, IPPROTO_IPV6, IPV6_PREFER_TEMPADDR,
                            &value, sizeof(value));
            if (rc < 0) {
                /* no error, warning only */
                do_log_error(L_WARN, errno, "Couldn't set IPV6CTL_USETEMPADDR");
            }
        }

#endif
    }
    return fd;
}
Beispiel #8
0
void think()
{
    fd_set readSet;
    struct timeval tv={1,0};
    unsigned int i;
    vector<int> toRemove;
    int maxfd = server;
    FD_ZERO(&readSet);
    FD_SET(server,&readSet);
    set<int>::iterator it;
    for (it=sockets.begin();it!=sockets.end();it++)
    {
	FD_SET(maxfd = *it, &readSet);
    }
    int sel = select(maxfd+1, &readSet,0,0,&tv);
    if (sel <= 0)
    {
	struct timespec ts={0,100000000};
	nanosleep(&ts,0);
    }
    if (FD_ISSET(server,&readSet))
    {
	int s = accept(server, 0, 0);
	if (s != -1 && sockets.size() < FD_SETSIZE)
	{
	    setNonblocking(s);
	    sockets.insert(s);
	}
    }
    for (it=sockets.begin();it!=sockets.end();it++)
    {
	if (FD_ISSET(*it, &readSet))
	{
	    int ret = recv(*it, buffer, BUFSIZE, 0);
	    if (ret <= 0)
		toRemove.push_back(*it);
	}
    }
    for (i=0;i<toRemove.size(); i++)
    {
	shutdown(toRemove[i],1);
	close(toRemove[i]);
	sockets.erase(toRemove[i]);
    }
}
Beispiel #9
0
static s32 helper_setup_socket( u16 port)
{
	s32 sock;
	int ret;
	//u32	clientlen;
	struct sockaddr_in server;
	struct sockaddr_in client;
	
	//clientlen = sizeof(client);

	sock = net_socket (AF_INET, SOCK_STREAM, IPPROTO_IP);

	if (sock == INVALID_SOCKET) {
		printf( "setup():INVALID_SOCKET\n");
		return -1;
	}

	memset (&server, 0, sizeof (server));
	memset (&client, 0, sizeof (client));

	server.sin_family = AF_INET;
	server.sin_port = htons (port);
	server.sin_addr.s_addr = INADDR_ANY;
	ret = net_bind (sock, (struct sockaddr *) &server, sizeof (server));
		
	if ( ret ) {
		printf( "net_bind():INVALID_SOCKET\n");
		net_close( sock); 
		return -1;
	}

	if ( (ret = net_listen( sock, 1)) ) {
		printf( "net_listen():INVALID_SOCKET\n");
		net_close( sock);
		return -1;
	}

#if	0
	ret = setNonblocking(sock);
	printf( "setNonblocking(%d) returns=%d.\n", sock, ret);
#endif
	return sock;
}
Beispiel #10
0
int _accept(int fd)
{
    int new_fd = -1;
    while (true)
    {
        struct sockaddr_in sock;
        socklen_t sockLen = sizeof(sock);
        new_fd = ::accept(fd, (struct sockaddr*)&sock, &sockLen);
        if (new_fd == -1)
        {
            if (errno == EINTR)
                continue;
            else
                return -1;
        }

        break;
    }

    if (setNonblocking(new_fd) == false)
    {
        LOG(ERROR) << "set socket nonblocking error\n";
        ::close(new_fd);
        return -1;
    }

    int send_buffer_size = SOCKET_BUFFER_SIZE;
    setsockopt(new_fd, SOL_SOCKET, SO_SNDBUF, (void*)&send_buffer_size, sizeof(send_buffer_size));

    int flags = 1;
    int ret = setsockopt(new_fd, SOL_SOCKET, SO_REUSEADDR, (void *)&flags, sizeof(flags));
    ret = setsockopt(new_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&flags, sizeof(flags));
    if (ret != 0)
        LOG(ERROR) << "setsockopt tcp_nodelay error\n";

    struct linger ling = {0, 0};
    setsockopt(new_fd, SOL_SOCKET, SO_LINGER, (void *)&ling, sizeof(ling));
    if (ret != 0)
        LOG(ERROR) << "setsockopt tcp_linger error\n";

    return new_fd;
}
Beispiel #11
0
int main(int argc, char* argv[])
{
    server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (server == -1)
	error("cannot create socket.");
    setNonblocking(server);
    struct sockaddr_in saddr;
    saddr.sin_family = AF_INET;
    saddr.sin_port = argc > 1 ? htons(atoi(argv[argc-1])) : htons(22222);
    saddr.sin_addr.s_addr = 0;
    if (bind(server, (struct sockaddr*)&saddr, sizeof(saddr)) == -1)
	error("cannot bind.");
    if (listen(server,1) == -1)
	error("cannot listen.");
    // cerr << "Starting server..." << endl;
    while (true)
    {
	think();
    }
}
Beispiel #12
0
void Socket::createSocket(const SocketAddress& sa) const
{
    SOCKET& socket = impl->fd;
    if (socket != INVALID_SOCKET) Socket::close();

    SOCKET s = ::socket (getAddrInfo(sa).ai_family,
                         getAddrInfo(sa).ai_socktype,
                         0);
    if (s == INVALID_SOCKET) throw QPID_WINDOWS_ERROR(WSAGetLastError());
    socket = s;

    try {
        if (nonblocking) setNonblocking();
        if (nodelay) setTcpNoDelay();
    } catch (std::exception&) {
        ::closesocket(s);
        socket = INVALID_SOCKET;
        throw;
    }
}
Beispiel #13
0
int main(int argc, char *argv[])
{
	int listenfd;
	struct sockaddr_in server_addr;
	int opt = 1;  //套接字选项
	int result;

	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if(listenfd == -1){
		perror("socket error");
		exit(1);
	}
	setNonblocking(listenfd);

	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);  //接受任意IP
	server_addr.sin_port = htons(PORT);

	//设置socket状态
	//SOL_SOCKET:存取socket层, SO_REUSEADDR:允许在bind()过程中本地址可重复使用
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

	//绑定套接字
	result = bind(listenfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
	if(result == -1){
		perror("socket bind error");
		exit(1);
	}

	result = listen(listenfd, LISTENQ);
	if(result == -1){
		perror("socket listen error");
		exit(1);
	}

	do_epoll(listenfd);

	return 0;
}
Beispiel #14
0
int
runRedirector(pid_t *pid_return, int *read_fd_return, int *write_fd_return)
{
    int rc, rc2, status;
    pid_t pid;
    int filedes1[2], filedes2[2];
    sigset_t ss, old_mask;

    assert(redirector);

    if(redirector_buffer == NULL) {
        redirector_buffer = malloc(REDIRECTOR_BUFFER_SIZE);
        if(redirector_buffer == NULL)
            return -errno;
    }

    rc = pipe(filedes1);
    if(rc < 0) {
        rc = -errno;
        goto fail1;
    }


    rc = pipe(filedes2);
    if(rc < 0) {
        rc = -errno;
        goto fail2;
    }

    fflush(stdout);
    fflush(stderr);
    flushLog();

    interestingSignals(&ss);
    do {
        rc = sigprocmask(SIG_BLOCK, &ss, &old_mask);
    } while (rc < 0 && errno == EINTR);
    if(rc < 0) {
        rc = -errno;
        goto fail3;
    }

    pid = fork();
    if(pid < 0) {
        rc = -errno;
        goto fail4;
    }

    if(pid > 0) {
        do {
            rc = sigprocmask(SIG_SETMASK, &old_mask, NULL);
        } while(rc < 0 && errno == EINTR);

        if(rc < 0) {
            rc = -errno;
            goto fail4;
        }

        rc = setNonblocking(filedes1[1], 1);
        if(rc >= 0)
            rc = setNonblocking(filedes2[0], 1);
        if(rc < 0) {
            rc = -errno;
            goto fail4;
        }

        /* This is completely unnecesary -- if the redirector cannot be
           started, redirectorStreamHandler1 will get EPIPE straight away --,
           but it improves error messages somewhat. */
        rc = waitpid(pid, &status, WNOHANG);
        if(rc > 0) {
            logExitStatus(status);
            rc = -EREDIRECTOR;
            goto fail4;
        } else if(rc < 0) {
            rc = -errno;
            goto fail4;
        }

        *read_fd_return = filedes2[0];
        *write_fd_return = filedes1[1];

        *pid_return = pid;
        /* This comes at the end so that the fail* labels can work */
        close(filedes1[0]);
        close(filedes2[1]);
    } else {
        close(filedes1[1]);
        close(filedes2[0]);
        uninitEvents();
        do {
            rc = sigprocmask(SIG_SETMASK, &old_mask, NULL);
        } while (rc < 0 && errno == EINTR);
        if(rc < 0)
            exit(142);

        if(filedes1[0] != 0)
            dup2(filedes1[0], 0);
        if(filedes2[1] != 1)
            dup2(filedes2[1], 1);

        execlp(redirector->string, redirector->string, NULL);
        exit(142);
        /* NOTREACHED */
    }
    return 1;

 fail4:
    do {
        rc2 = sigprocmask(SIG_SETMASK, &old_mask, NULL);
    } while(rc2 < 0 && errno == EINTR);
 fail3:
    close(filedes2[0]);
    close(filedes2[1]);
 fail2:
    close(filedes1[0]);
    close(filedes1[1]);
 fail1:
    free(redirector_buffer);
    redirector_buffer = NULL;
    return rc;
}
int main(int argc, char **argv) {
    int port = 22000;
    std::string host = "127.0.0.1";
    if (argc >= 3) {
        host = argv[1];
        port = atoi(argv[2]);
    }
    LOG("LISTEN " << host << ":" << port);

    int events_fd = kqueue();
    if (events_fd < 0) {
        err(1, "\t%s:%d", __FILE__, __LINE__);
    }
    fdMap[events_fd] = FDType::events;

    struct sockaddr_in servaddr;
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(port);
    inet_pton(AF_INET, host.c_str(), &(servaddr.sin_addr));

    int listen_fd = ::socket(AF_INET, SOCK_STREAM, 0);
    if (listen_fd < 0) {
        err(1, "\t%s:%d", __FILE__, __LINE__);
    }
    fdMap[listen_fd] = FDType::listen;

    int enable = 1;
    if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) < 0) {
        err(1, "setsockopt(SO_REUSEADDR) failed %s:%d", __FILE__, __LINE__);
    }

    if (::bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) {
        err(1, "Error bind \t%s:%d", __FILE__, __LINE__);
    }
    if (::listen(listen_fd, 10) < 0) {
        err(1, "\t%s:%d", __FILE__, __LINE__);
    }
    setNonblocking(listen_fd);

    kqAdd(listen_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0);

    struct kevent events[MAX_EVENTS];
    while (1) {
        int events_size = ::kevent(events_fd, events_to_monitor, events_to_monitor_size, events, MAX_EVENTS, 0);
        events_to_monitor_size = 0;
        for (int i = 0; i < events_size; ++i) {
            struct kevent &event = events[i];
            LOG(event);
            int fd = (int) event.ident;
            auto fdMapIt = fdMap.find(fd);
            if (fdMapIt == fdMap.end()) {
                warn("Error accepting \t%s:%d", __FILE__, __LINE__);
                continue;
            }
            switch (fdMapIt->second) {
                case FDType::listen : {
                    struct sockaddr_in client_addr;
                    socklen_t ca_len = sizeof(client_addr);
                    int client_fd = accept(fd, (struct sockaddr *) &client_addr, &ca_len);
                    LOG("accept(" << fd << ") return " << client_fd);
                    if (client_fd < 0) {
                        warn("Error accepting \t%s:%d", __FILE__, __LINE__);
                        continue;
                    }
                    LOG("Client connected: " << inet_ntoa(client_addr.sin_addr) << ":" << ntohs(client_addr.sin_port));
                    fdMap[client_fd] = FDType::client;
                    setNonblocking(client_fd);

                    kqAdd(client_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0);
                    kqAdd(client_fd, EVFILT_WRITE, EV_ADD | EV_DISABLE, 0);
                    break;
                }
                case FDType::client : {
                    if (event.filter == EVFILT_READ) {
                        if (event.flags & EV_EOF) {
                            LOG("close(" << fd << ")");
                            close(fd);
                            break;
                        }

                        char buffer[BUFFER_SIZE];
                        int received = ::recv(fd, buffer, BUFFER_SIZE, 0);
                        if (received < 0) {
                            warn("Error reading from socket \t%s:%d", __FILE__, __LINE__);
                            break;
                        }
                        if (received == 0) {
                            LOG("close(" << fd << ")");
                            close(fd);
                            break;
                        } else {
                            buffer[received] = 0;
                            LOG("Reading " << received << " bytes: '" << buffer << "'");
                        }
                        if (::send(fd, buffer, received, 0) != received) {
                            warn("Could not write to stream \t%s:%d", __FILE__, __LINE__);
                            continue;
                        }
                    }
                    break;
                }
            }
        }
    }
    close(events_fd);
}
Beispiel #16
0
static int count_connects(int ipadr, int portnum, int want)
{
	int i;
	int maxfd;
	int nopen;
	struct pollfd pfds[65536];
	int nok;
	int nrej;
	time_t end;

#ifdef VERBOSE
	printf("Starting connections until we can't start any more; will print what stops us to stderr.\n");
#endif
	for (i = 0; i < want; i++) {
		struct sockaddr_in srv_addr;
		int err;

		fds[i] = socket(AF_INET, SOCK_STREAM, 0);
		if (fds[i] < 0) {
#ifdef VERBOSE
			perror("socket");
#endif
			break;
		}
		setNonblocking(fds[i]);	/* else connect will wait until resources avail */

		memset((char *) &srv_addr, 0, sizeof(srv_addr));
		srv_addr.sin_family = AF_INET;
		srv_addr.sin_addr.s_addr = ipadr;
		srv_addr.sin_port = htons(portnum);	/* daytime service */

		err = connect(fds[i], (struct sockaddr *) &srv_addr, sizeof(srv_addr));
		if ((err != 0) && (errno != EINPROGRESS)) {
#ifdef VERBOSE
			perror("connect");
#endif
			break;
		}
		
		pfds[i].fd = fds[i];
		pfds[i].events = POLLOUT;
	}
	maxfd = i;
#ifdef VERBOSE
	printf("%d connections in progress...\n", maxfd);
#endif

	/* Now sit until they all connect or fail, or until five seconds
	 * pass, whichever comes first.
	 */
	end = time(0) + 6;
	for (nrej=nok=0, nopen=maxfd; nopen; ) {
		int nready;
		if ((end - time(0)) < 0)
			break;
		nready = poll(pfds, maxfd, 1000);
		if (nready < 0) {
			perror("poll");
			exit(1);
		}
		for (i=0; i<maxfd; i++) {
			if ((pfds[i].fd == -1) || !pfds[i].revents)
				continue;

			/* question: if a connect fails, will it show up first
			 * as a POLLERR, POLLHUP, or POLLOUT?
			 */
			if (pfds[i].revents & (POLLHUP|POLLERR)) {
				/* connect failed? */
				close(pfds[i].fd);
				nrej++;
			} else if (pfds[i].revents & POLLOUT) {
				/* check to see if connect succeeded */
				int connecterr = -1;
				socklen_t len = sizeof(connecterr);
				if (getsockopt(pfds[i].fd, SOL_SOCKET, SO_ERROR, (char *)&connecterr, &len) < 0) {
					perror("getsockopt");
					exit(1);
				}
				if (!connecterr) {
					nok++;
					/* keep socket open */
				} else if (connecterr ==  ECONNREFUSED) {
					close(pfds[i].fd);
					nrej++;
				}
			} else {
				printf("bad poll result: pfds[%d].fd %d, .revents %x\n", i, pfds[i].fd, pfds[i].revents);
				exit(1);
			}
			pfds[i].fd = -1;
			nopen--;
		}
	}

	/* Close 'em (might close a few extra, but that's ok) */
	for (i = 0; i < maxfd; i++)
		close(fds[i]);

#ifdef VERBOSE
	printf("%d connections accepted, %d rejected, %d pending\n", nok, nrej, nopen);
#endif
	return nok + nrej + nopen;
}
Beispiel #17
0
void run()
{
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = htons(SERVER_PORT);

    int server_socket = socket(PF_INET, SOCK_STREAM, 0);
    if( server_socket < 0) {
        printf("Create Socket Failed!");
        exit(1);
    }
    int opt = 1;
    setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR,&opt, sizeof(opt));
    setNonblocking(server_socket);

    if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))) {
        printf("Server Bind Port : %d Failed!", SERVER_PORT); 
        exit(1);
    }

    if (listen(server_socket, LENGTH_OF_LISTEN_QUEUE) ) {
        printf("Server Listen Failed!"); 
        exit(1);
    }

    int efd = epoll_create(MAXEVENTS);
    if (efd == -1) {
        perror ("epoll_create");
        return;
    }

    struct epoll_event server_event;
    server_event.data.ptr = new Connection(server_socket);
    server_event.events = EPOLLIN;
    printf("epoll_ctl [%d]\n", epoll_ctl(efd, EPOLL_CTL_ADD, server_socket, &server_event));

    struct epoll_event events[MAXEVENTS];
    while (1) {
        fflush(stdout);
        int n = epoll_wait (efd, events, MAXEVENTS, -1);
//        printf("epoll_wait [%d] events\n", n);
        for (int i = 0; i < n; i++) {
            Connection* conn = (Connection*)(events[i].data.ptr);
            if (conn == NULL) {
                printf("invalid conn[%p]", conn);
                continue;
            }

            if ((events[i].events & EPOLLERR) ||
                    (events[i].events & EPOLLHUP)) {
                printf("epoll error\n");
                printf("epoll_del [%d]\n", epoll_ctl(efd, EPOLL_CTL_DEL, conn->GetFd(), NULL));
                close(conn->GetFd());
                delete conn;
                continue;
            }

            if (conn->GetFd() == server_socket) {
                struct sockaddr_in client_addr;
                socklen_t length = sizeof(client_addr);
                int new_socket = accept(server_socket,(struct sockaddr*)&client_addr,&length);
                if (new_socket < 0) {
                    printf("Server Accept Failed!\n");
                    break;
                }
                setNonblocking(new_socket);
                Connection* conn = new Connection(new_socket);
                struct epoll_event* event = new struct epoll_event;
                event->data.ptr = conn;
                event->events = EPOLLIN|EPOLLET;
//                event->events = EPOLLIN;
                int ret = epoll_ctl(efd, EPOLL_CTL_ADD, conn->GetFd(), event);
                if (ret != 0) {
                    printf("epoll_add read [%d] %d %s\n", ret, errno, strerror(errno));
                }
            } else {
                RETCODE retCode = conn->Handle(events[i].events);
                if (retCode == DELETE) {
                    int ret = epoll_ctl(efd, EPOLL_CTL_DEL, conn->GetFd(), NULL);
                    if (ret != 0) {
                        printf("epoll_del [%d]\n\n\n", epoll_ctl(efd, EPOLL_CTL_DEL, conn->GetFd(), NULL));
                    }
                    printf("\n\n\n");
                    close(conn->GetFd());
                    delete conn;
                } else if (retCode == ADDOUT) {
                    struct epoll_event* event = new struct epoll_event;
                    event->data.ptr = conn;
                    event->events = EPOLLOUT|EPOLLET;
//                    event->events = EPOLLOUT;
                    int ret = epoll_ctl(efd, EPOLL_CTL_MOD, conn->GetFd(), event);
                    if (ret != 0) {
                        printf("epoll_add write [%d] %d %s\n", ret, errno, strerror(errno));
                    }
                }
            }

        }
    } // while accept()


    close(server_socket);
}
int EpollSocket::start_epoll(int port, EpollSocketWatcher &socket_handler, int backlog) {
	int sockfd = this->listen_on(port, backlog);

	struct epoll_event ev;
	int epollfd = epoll_create(10);
	if (epollfd == -1) {
		perror("epoll_create");
		exit(EXIT_FAILURE);
	}

	ev.events = EPOLLIN;
	ev.data.fd = sockfd;
	if(epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev) == -1) {
		perror("epoll_ctl: listen_sock");
		exit(EXIT_FAILURE);
	}

	epoll_event events[10];

	while(1) {
		int fds_num = epoll_wait(epollfd, events, 10, -1);
		if(fds_num == -1) {
			perror("epoll_pwait");
			exit(EXIT_FAILURE);
		}

		for (int i = 0; i < fds_num; i++) {
			if(events[i].data.fd == sockfd) {
				int conn_sock = accept_socket(sockfd);
				setNonblocking(conn_sock);
				LOG_DEBUG("get accept socket which listen fd:%d, conn_sock_fd:%d", sockfd, conn_sock);

				EpollContext *epoll_context = new EpollContext();
				epoll_context->fd = conn_sock;

				socket_handler.on_accept(*epoll_context);

				epoll_event conn_sock_ev;
				conn_sock_ev.events = EPOLLIN | EPOLLET;
				conn_sock_ev.data.ptr = epoll_context;

				if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &conn_sock_ev) == -1) {
				   perror("epoll_ctl: conn_sock");
				   exit(EXIT_FAILURE);
				}

			} else if(events[i].events & EPOLLIN ){ // readable
				EpollContext *epoll_context = (EpollContext *) events[i].data.ptr;
				int fd = epoll_context->fd;

				int buffer_size = 1024;
				char read_buffer[buffer_size];
				memset(read_buffer, 0, buffer_size);
				int read_size = 0;

				while((read_size = recv(fd, read_buffer, buffer_size, 0)) > 0) {
					LOG_DEBUG("read success which read size:%d", read_size);

					int ret = socket_handler.on_readable(*epoll_context, read_buffer, buffer_size, read_size);
					if(ret != 0) {
						close_and_release(epollfd, events[i], socket_handler);
						continue;
					}
					memset(read_buffer, 0, buffer_size); // reset buffer for next read
				}

				if(read_size == 0 /* connect close*/ || (read_size == -1 && errno != EAGAIN) /* io error*/) {
					LOG_DEBUG("read_size not normal which size:%d", read_size);
					close_and_release(epollfd, events[i], socket_handler);
					continue;
				}

				events[i].events = EPOLLOUT | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &events[i]);

			} else if(events[i].events & EPOLLOUT) { // writeable
				EpollContext *epoll_context = (EpollContext *) events[i].data.ptr;
				int fd = epoll_context->fd;
				LOG_DEBUG("start write data");

				int ret = socket_handler.on_writeable(*epoll_context);
				if(ret != 0) {
					close_and_release(epollfd, events[i], socket_handler);
					continue;
				}

				events[i].events = EPOLLIN | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &events[i]);
			} else {
				LOG_INFO("unkonw events :%d", events[i].events);
				continue;
			}
		}
	}
}
Beispiel #19
0
struct process* accept_sock ( int listen_sock )
{
    int s;
    // 在ET模式下必须循环accept到返回-1为止
    while ( 1 )
    {
        struct sockaddr in_addr;
        socklen_t in_len;
        int infd;
        char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
        if ( current_total_processes >= MAX_PORCESS )
        {
            // 请求已满,accept之后直接挂断
            infd = accept ( listen_sock, &in_addr, &in_len );
            if ( infd == -1 )
            {
                if ( ( errno == EAGAIN ) ||
                        ( errno == EWOULDBLOCK ) )
                {
                    /* We have processed all incoming
                      connections. */
                    break;
                }
                else
                {
                    perror ( "accept" );
                    break;
                }
            }
            close ( infd );

            return;
        }

        in_len = sizeof in_addr;
        infd = accept ( listen_sock, &in_addr, &in_len );
        if ( infd == -1 )
        {
            if ( ( errno == EAGAIN ) ||
                    ( errno == EWOULDBLOCK ) )
            {
                /* We have processed all incoming
                   connections. */
                break;
            }
            else
            {
                perror ( "accept" );
                break;
            }
        }

        getnameinfo ( &in_addr, in_len,
                      hbuf, sizeof hbuf,
                      sbuf, sizeof sbuf,
                      NI_NUMERICHOST | NI_NUMERICSERV );
        /* Make the incoming socket non-blocking and add it to the
           list of fds to monitor. */
        s = setNonblocking ( infd );
        if ( s == -1 )
            abort ();
        int on = 1;
        setsockopt ( infd, SOL_TCP, TCP_CORK, &on, sizeof ( on ) );
        //添加监视sock的读取状态
        event.data.fd = infd;
        event.events = EPOLLIN | EPOLLET;
        s = epoll_ctl ( efd, EPOLL_CTL_ADD, infd, &event );
        if ( s == -1 )
        {
            perror ( "epoll_ctl" );
            abort ();
        }
        struct process* process = find_empty_process_for_sock ( infd );
        current_total_processes++;
        reset_process ( process );
        process->sock = infd;
        process->fd = NO_FILE;
        process->status = STATUS_READ_REQUEST_HEADER;
    }
}
Beispiel #20
0
FdEventHandlerPtr
create_listener(char *address, int port,
		int (*handler) (int, FdEventHandlerPtr, AcceptRequestPtr),
		void *data)
{
	int fd, rc;
	int one = 1;
	int done;
	struct sockaddr_in addr;
	int inet6 = 0;

	if (inet6 && address) {
		struct in_addr buf;
		rc = inet_aton(address, &buf);
		if (rc == 1)
			inet6 = 0;
	}
	fd = -1;
	errno = EAFNOSUPPORT;
	if (fd < 0 && (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)) {
		inet6 = 0;
		fd = socket(PF_INET, SOCK_STREAM, 0);
	}

	if (fd < 0) {
		done = (*handler) (-errno, NULL, NULL);
		assert(done);
		return NULL;
	}

	rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one,
			sizeof(one));
	if (rc < 0)
		do_log_error(L_WARN, errno, "Couldn't set SO_REUSEADDR");

	if (inet6) {
		rc = -1;
		errno = EAFNOSUPPORT;
	} else {
		memset(&addr, 0, sizeof(addr));
		rc = inet_aton(address, &addr.sin_addr);
		if (rc != 1) {
			done =
			    (*handler) (rc == 0 ? -ESYNTAX : -errno, NULL,
					NULL);
			assert(done);
			return NULL;
		}
		addr.sin_family = AF_INET;
		addr.sin_port = htons(port);
		rc = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
	}

	if (rc < 0) {
		do_log_error(L_ERROR, errno, "Couldn't bind");
		CLOSE(fd);
		done = (*handler) (-errno, NULL, NULL);
		assert(done);
		return NULL;
	}

	rc = setNonblocking(fd, 1);
	if (rc < 0) {
		do_log_error(L_ERROR, errno, "Couldn't set non blocking mode");
		CLOSE(fd);
		done = (*handler) (-errno, NULL, NULL);
		assert(done);
		return NULL;
	}

	rc = listen(fd, 32);
	if (rc < 0) {
		do_log_error(L_ERROR, errno, "Couldn't listen");
		CLOSE(fd);
		done = (*handler) (-errno, NULL, NULL);
		assert(done);
		return NULL;
	}

	/* do_log(L_INFO, "Established listening socket on port %d.\n", port); */

	return schedule_accept(fd, handler, data);
}
Beispiel #21
0
int main ( int argc, char *argv[] )
{
    int s;
    struct epoll_event *events;

    signal ( SIGABRT, &sighandler );
    signal ( SIGTERM, &sighandler );
    signal ( SIGINT, &sighandler );

    if ( argc != 3 )
    {
        fprintf ( stderr, "Usage: %s [port] [doc root]\n", argv[0] );
        exit ( EXIT_FAILURE );
    }

    init_processes();

    listen_sock = create_and_bind ( argv[1] );
    doc_root = argv[2];
    if ( listen_sock == -1 )
        abort ();

    s = setNonblocking ( listen_sock );
    if ( s == -1 )
        abort ();

    s = listen ( listen_sock, SOMAXCONN );
    if ( s == -1 )
    {
        perror ( "listen" );
        abort ();
    }

    efd = epoll_create1 ( 0 );
    if ( efd == -1 )
    {
        perror ( "epoll_create" );
        abort ();
    }

    event.data.fd = listen_sock;
    event.events = EPOLLIN | EPOLLET;
    s = epoll_ctl ( efd, EPOLL_CTL_ADD, listen_sock, &event );
    if ( s == -1 )
    {
        perror ( "epoll_ctl" );
        abort ();
    }

    /* Buffer where events are returned */
    events = calloc ( MAXEVENTS, sizeof event );

    /* The event loop */
    while ( 1 )
    {
        int n, i;

        n = epoll_wait ( efd, events, MAXEVENTS, -1 );
        if ( n == -1 )
        {
            perror ( "epoll_wait" );
        }
        for ( i = 0; i < n; i++ )
        {
            if ( ( events[i].events & EPOLLERR ) ||
                    ( events[i].events & EPOLLHUP ) )
            {
                /* An error has occured on this fd, or the socket is not
                   ready for reading (why were we notified then?) */
                fprintf ( stderr, "epoll error\n" );
                close ( events[i].data.fd );
                continue;
            }

            handle_request ( events[i].data.fd );

        }
    }

    free ( events );

    close ( listen_sock );

    return EXIT_SUCCESS;
}
Beispiel #22
0
void
call_udpl_epoll(struct sockaddr_in servaddr, unsigned expected_size,
    unsigned *latency, size_t sender_buf_size)
{
    int sockfd;
    char buf[BUF_SIZE];

    struct timespec start;
    struct timespec end;

    int n, i;
    size_t sent_size=0;
    size_t max_send_size=0;

    struct epoll_event ev, events[MAX_EVENTS];
    int nfds, epollfd;

    struct timespec wait_for_server={.tv_sec=0, .tv_nsec=INTERVAL};

    assert(sender_buf_size <= BUF_SIZE);

    nanosleep(&wait_for_server, NULL);
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (setNonblocking(sockfd) != 0) perror("setNonblocking");

    epollfd = epoll_create(16);
    if (epollfd == -1) {
        perror("epoll_create");
        exit(EXIT_FAILURE);
    }

    ev.events = EPOLLIN;
    ev.data.fd = sockfd;
    // need not care about blocking
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev) == -1) {
        perror("epoll_ctl: sockfd");
        exit(EXIT_FAILURE);
    }

    max_send_size = MIN(MAX_UDP_SIZE, MIN(expected_size, sender_buf_size));
    clock_gettime(CLOCK_MONOTONIC, &start);
    // send something first
    n = sendton(sockfd, buf, max_send_size, 0,
        (struct sockaddr *)&servaddr, sizeof(servaddr));
    if (n < 0)
        perror("client sendto");

    while (sent_size < expected_size) {
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, -1);
        if (nfds == -1) {
            perror("epoll_pwait");
            exit(EXIT_FAILURE);
        }

        for (i = 0; i < nfds; ++i) {
            if (events[i].events & EPOLLIN) { // readable
                n = Readn(events[i].data.fd, buf, BUF_SIZE);
                sent_size += n; // only the echoed size is effective
                if (DEBUG) printf("%u / %u<<<<%u / %u echo rate\n", n, MIN(max_send_size, expected_size - sent_size), sent_size, expected_size);
                if (sendton(sockfd, buf, MIN(max_send_size, expected_size - sent_size), 0,
                    (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
                    perror("client sendto");
            }
        }
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    *latency = ((end.tv_sec - start.tv_sec) * 1000000000 +
        end.tv_nsec - start.tv_nsec) / 2;
    close(sockfd);
}


void
call_udpt_epoll(struct sockaddr_in servaddr, unsigned expected_size,
    unsigned *latency, size_t sender_buf_size, size_t *received)
{
    int sockfd;
    char buf[BUF_SIZE];

    struct timespec start;
    struct timespec end;

    int n, i, ret;
    size_t sent_size=0;
    size_t max_send_size, send_size;

    struct epoll_event ev, events[MAX_EVENTS];
    int nfds, epollfd;

    struct timespec wait_for_server={.tv_sec=0, .tv_nsec=INTERVAL};

    assert(sender_buf_size <= BUF_SIZE);

    nanosleep(&wait_for_server, NULL);
    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (setNonblocking(sockfd) != 0) perror("setNonblocking");

    epollfd = epoll_create(16);
    if (epollfd == -1) {
        perror("epoll_create");
        exit(EXIT_FAILURE);
    }

    ev.events = EPOLLIN;
    ev.data.fd = sockfd;
    // need not care about blocking
    if (epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev) == -1) {
        perror("epoll_ctl: sockfd");
        exit(EXIT_FAILURE);
    }

    max_send_size = MIN(MAX_UDP_SIZE, MIN(expected_size, sender_buf_size));
    *received = 0;
    clock_gettime(CLOCK_MONOTONIC, &start);

    // when performing throughput, sender needs not to care about receiver
    while (sent_size < expected_size) {
        send_size = MIN(max_send_size, expected_size - sent_size);
        Sendton(sockfd, buf, send_size, 0,
            (struct sockaddr *)&servaddr, sizeof(servaddr));
        if (DEBUG) printf("%u>>>>%u / %u sendto\n", send_size, sent_size, expected_size);
        sent_size += send_size;
    }
    if (DEBUG) printf("client finished throughput sent %u\n", sent_size);

    // the second while is used to receive multiple reply

    while (1) {
        nfds = epoll_wait(epollfd, events, MAX_EVENTS, EPOLL_MILLI_TIMEOUT);
        if (nfds == -1) {
            perror("epoll_pwait");
            exit(EXIT_FAILURE);
        } else if (nfds == 0)
            break;

        for (i = 0; i < nfds; ++i) {
            if (events[i].events & EPOLLIN) { // readable
                while (1) {
                    // since server will respond to every sent packet, there may be multiple responds
                    ret = read(events[i].data.fd, &n, sizeof(int));
                    if (ret < 0) {
                        if (!((errno == EAGAIN) || (errno == EWOULDBLOCK)))
                            perror("read error other than nonblock read");
                        break;
                    } else if (ret == 0) // end of file
                        break;
                    else {
                        // single "ack" response contributes a small amount of time
                        clock_gettime(CLOCK_MONOTONIC, &end);
                        *received += n;
                        if (DEBUG) printf("<<<<%u echoed\n", n);
                    }
                }
                if (DEBUG) printf("%i / %u ack Received\n", *received, expected_size);
            }
        }
    }
    *latency = (end.tv_sec - start.tv_sec) * 1000000000 +
        end.tv_nsec - start.tv_nsec;
    close(sockfd);
}


#ifdef CLIENT_MAIN
int main(int argc, char**argv)
{
    struct sockaddr_in servaddr;
    unsigned chunk_size[] = {4, 16, 64, 256, 1024, 4*1024, 16*1024, 64*1024, 256*1024, 512*1024, 32*1024, 48*1024, 96*1024, 128*1024};
    //unsigned chunk_size[] = {4, 16, 64, 256, 1024, 4*1024, 16*1024, 32*1024, 64*1024, 96*1024, 128*1024};
    unsigned latency, total_time;
    size_t received;
    int i;
    int repeat=1;
    size_t sender_buf_size=1024;

    if (argc >= 5)
        sender_buf_size = atoi(argv[4]);
    if (argc >= 4)
        repeat = atoi(argv[3]);

    if (argc < 3) {
        printf("usage: [udp|tcp] <IP address> <repeat times> <sender_buf_size=1024>\n");
        exit(1);
    }

    bzero(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr=inet_addr(argv[2]);
    servaddr.sin_port=htons(PORT);

    while (repeat) {
        if (strcmp(argv[1], "udp") == 0) {
            printf("SIZE\tUDP latency us\tUDP througput MB/s\tLOST\tLOSS rate%%\n");
            for (i=0; i<sizeof(chunk_size) / sizeof(chunk_size[0]); i++) {
                call_udp(servaddr, 1, chunk_size[i], &latency, NULL);
                call_udp(servaddr, 0, chunk_size[i], &total_time, &received);
                printf("%8u\t%8u\t%8.2f\t%8u\t%8.2f\n", chunk_size[i], latency / 1000,
                    chunk_size[i] * 1000000000.0 / total_time / 1024 / 1024, chunk_size[i] - received,
                    (chunk_size[i] - received) * 100.0 / chunk_size[i]);
            }
        } else if (strcmp(argv[1], "udpl") == 0) {
            printf("SIZE\tUDP latency us\tsender_buf_size: %i\n", sender_buf_size);
            for (i=0; i<sizeof(chunk_size) / sizeof(chunk_size[0]); i++) {
                call_udpl_epoll(servaddr, chunk_size[i], &latency, sender_buf_size);
                printf("%8u\t%8u\n", chunk_size[i], latency / 1000);
            }
        } else if (strcmp(argv[1], "udpt") == 0) {
            printf("SIZE\tUDP throughput MB/s\tLOST\tLOSS Rate%%\tsender_buf_size: %i\n", sender_buf_size);
            for (i=0; i<sizeof(chunk_size) / sizeof(chunk_size[0]); i++) {
                call_udpt_epoll(servaddr, chunk_size[i], &latency, sender_buf_size, &received);
                printf("%8u\t%8.2f\t%8u\t%8.2f\n", chunk_size[i],
                    chunk_size[i] * 1000000000.0 / latency / 1024 / 1024,
                    chunk_size[i] - received,
                    (chunk_size[i] - received) * 100.0 / chunk_size[i]);
            }
        } else if (strcmp(argv[1], "tcp") == 0) {
            printf("SIZE\tTCP latency us\tTCP througput MB/s\tLOST\tLOSS rate\n");
            for (i=0; i<sizeof(chunk_size) / sizeof(chunk_size[0]); i++) {
                call_tcp(servaddr, 1, chunk_size[i], &latency, NULL);
                call_tcp(servaddr, 0, chunk_size[i], &total_time, &received);
                printf("%8u\t%8u\t%8.2f\t%8u\t%8.2f\n", chunk_size[i], latency / 1000,
                    chunk_size[i] * 1000000000.0 / total_time / 1024 / 1024, chunk_size[i] - received,
                    (chunk_size[i] - received) * 100.0 / chunk_size[i]);
            }
        }
        repeat--;
    }
}
Beispiel #23
0
int writeStringToFile(int i_fd, const char* ccp_text)
{
    struct pollfd poll_fd[1];
    int i_text_length = 0;
    int i_poll_result = 0;
    int i_num_polls = 1;
    ssize_t written_bytes = 0;
    ssize_t total_written_bytes = 0;
    
    if(ccp_text == NULL)
    {
        return EXIT_FAILURE;
    }
    
    if (setNonblocking(i_fd))
    {
        debug(HTTP_RESPONSE, "Setting output stream non-blocking failed.\n");
        return EXIT_FAILURE;
    }
    
    i_text_length = strlen(ccp_text);
    
    poll_fd[0].fd = i_fd;
    poll_fd[0].events = POLLOUT;
    poll_fd[0].revents = 0;
    
    while(total_written_bytes < i_text_length)
    {
        i_poll_result = poll(poll_fd, i_num_polls, si_cgi_timeout_);
        
        if(i_poll_result < 0)
        {
            debug(HTTP_RESPONSE, "Polling on output stream failed.");
            return EXIT_FAILURE;
        }
        
        if(i_poll_result == 0)
        {
            debug(HTTP_RESPONSE, "Output stream timed out.");
            return EXIT_FAILURE;
        }
        
        if((poll_fd[0].revents & (POLLERR)) || ((!poll_fd[0].revents) & (POLLHUP)))
        {
            debug(HTTP_RESPONSE, "A problem occurred on the output stream.");
            return EXIT_FAILURE;
        }
        
        written_bytes = write(poll_fd[0].fd, ccp_text + (total_written_bytes), i_text_length - total_written_bytes);
        total_written_bytes += written_bytes;
        if (written_bytes < 0) 
        {       
            if(errno != EAGAIN)
            {
                debug(HTTP_RESPONSE, "Error while writing on output stream.\n");
                return EXIT_FAILURE;
            }

        }
    }    
    
    return EXIT_SUCCESS;
}
Beispiel #24
0
/**
 * struct sockaddr_in serv: 
 *
 * Descriptions
 **/
void
call_tcp(struct sockaddr_in servaddr, bool require_echo, unsigned expected_size,
    unsigned *latency, size_t *received)
{
    int sockfd;
    char buf[BUF_SIZE];

    struct timespec start;
    struct timespec end;
    int optval=1;

    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if (setsockopt(sockfd, IPPROTO_IP, TCP_NODELAY, &optval, sizeof(optval)) != 0)
        perror("setsockopt TCP_NODELAY");
    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
        perror("connect");

    struct timespec wait_for_server={.tv_sec=0, .tv_nsec=INTERVAL};
    nanosleep(&wait_for_server, NULL);

    Writen(sockfd, &expected_size, sizeof(unsigned));
    Writen(sockfd, &require_echo, sizeof(bool));
    // could ignore the header time
    clock_gettime(CLOCK_MONOTONIC, &start);
    Writen(sockfd, buf, expected_size);
    if (DEBUG) printf("buf sent\n");
    if (require_echo) {
        // measuring latency
        Readn(sockfd, buf, expected_size);
        clock_gettime(CLOCK_MONOTONIC, &end);
        *latency = ((end.tv_sec - start.tv_sec) * 1000000000 +
            end.tv_nsec - start.tv_nsec) / 2;
    } else {
        // measuring througput
        Readn(sockfd, received, sizeof(received));
        clock_gettime(CLOCK_MONOTONIC, &end);
        *latency = ((end.tv_sec - start.tv_sec) * 1000000000 +
            end.tv_nsec - start.tv_nsec);
    }
    close(sockfd);
}


void
call_udp(struct sockaddr_in servaddr, bool require_echo, unsigned expected_size,
    unsigned *latency, size_t *received)
{
    int sockfd;
    char buf[BUF_SIZE];

    struct timespec start;
    struct timespec end;

    struct SimpleProtocol data;

    data.require_echo = require_echo;
    data.expected_size = expected_size;

    sockfd=socket(AF_INET, SOCK_DGRAM, 0);

    Sendton(sockfd, &data, sizeof(data), 0,
        (struct sockaddr *)&servaddr, sizeof(servaddr));
    clock_gettime(CLOCK_MONOTONIC, &start);
    Sendton(sockfd, buf, expected_size, 0,
        (struct sockaddr *)&servaddr, sizeof(servaddr));
    if (DEBUG) printf("request sent: expected_size=%u, require_echo=%i,  Reading...\n",
        data.expected_size, data.require_echo);
    if (data.require_echo) {
        // measuring latency
        // prevent client from blocking on receiving less data than expected
        setNonblocking(sockfd);
        Readn(sockfd, buf, expected_size);
        clock_gettime(CLOCK_MONOTONIC, &end);
        *latency = ((end.tv_sec - start.tv_sec) * 1000000000 +
            end.tv_nsec - start.tv_nsec) / 2;
    } else {
        // measuring througput
        Readn(sockfd, received, sizeof(int));
        clock_gettime(CLOCK_MONOTONIC, &end);
        *latency = ((end.tv_sec - start.tv_sec) * 1000000000 +
            end.tv_nsec - start.tv_nsec);
        if (DEBUG) printf("SUMMARY: %i of %u sent\n", *received, expected_size);
    }
    close(sockfd);
}
Beispiel #25
0
/** tiniweb main routine
* @param argc number of commandline arguments
* @param argv arguments itself
* @return tiniweb return value
*/
int main(int argc, char** argv) {
    
    int c = 0;
    int i_option_index = 0;
    bool b_static = FALSE;
    char* cp_mapped_path = NULL;
    char* cp_path_to_htdigest_file = NULL;
    char* cp_search_path_root = NULL;
    bool b_digest_file_available = FALSE;
    bool b_authenticated = FALSE;
    
    
    // command line parsing: like done in example from
    // http://www.gnu.org/s/libc/manual/html_node/Getopt-Long-Option-Example.html
    while (1) {
        
        static struct option long_options[] = {
            { "web-dir", required_argument, 0, 0 },
            { "cgi-dir", required_argument, 0, 1 },
            { "cgi-timeout", required_argument, 0, 2 },
            { "secret", required_argument, 0, 3},
            { "verbose", no_argument, 0, 4 },
            { 0, 0, 0, 0 }
        };
            i_option_index = 0;
            c = getopt_long(argc, argv, "", long_options, &i_option_index);
            
            if (c == -1)
                break;
            
            switch (c) {
                case 0:
                    scp_web_dir_ = secPrint2String("%s", optarg);
                    debugVerbose(MAIN, "option web-dir used with argument: %s \n", scp_web_dir_);
                    break;
                case 1:
                    scp_cgi_dir_ = secPrint2String("%s",optarg);
                    debugVerbose(MAIN, "option cgi-dir used with argument: %s \n", scp_cgi_dir_);
                    break;
                case 2:
                    debugVerbose(MAIN, "option cgi-timeout used with argument: %s \n",
                    optarg);
                    si_cgi_timeout_ = (int) strtol(optarg, NULL, 10);
                    si_cgi_timeout_ *= 1000;
                    break;
                case 3:
                    scp_secret_ = secPrint2String("%s", optarg);
                    debugVerbose(MAIN, "option secret used with argument: %s \n", scp_secret_);
                    break;
                case 4:
                    b_flag_verbose_ = TRUE;
                    debugVerbose(MAIN, "switching to verbose mode \n");
                    break;
                default:
                    debug(MAIN, "encountert unknown argument \n");
                    secExit(STATUS_CANCEL);
                    break;
            }
    }
    
    if(!scp_cgi_dir_ || !scp_web_dir_ || !scp_secret_){
        debug(MAIN, "Mandatory parameter missing\n");
        debug(MAIN, "usage: ./tiniweb (--verbose) --web-dir <path> --cgi-dir <path> --secret <secret> (--cgi-timeout <msec>)\n");
        secExit(STATUS_CANCEL);
    }
    if (performPathChecking(&scp_cgi_dir_, &scp_web_dir_) == FALSE)
    {
        debug(MAIN, "ERROR, Paths not valid!\n");
        secExit(STATUS_CANCEL);
    }
    
    if(si_cgi_timeout_ < CGI_TIME_OUT_MIN)
    {
        debug(MAIN, "cgi-timeout is too short, using default value (%d)\n", CGI_TIME_OUT_MIN);
        si_cgi_timeout_ = CGI_TIME_OUT_MIN;
    }
    else if(si_cgi_timeout_ > CGI_TIME_OUT_MAX)
    {
        debug(MAIN, "cgi-timeout is too long, using default value (%d)\n", CGI_TIME_OUT_MAX);
        si_cgi_timeout_ = CGI_TIME_OUT_MAX;
    }
    
    
    
    debug(MAIN, "Argument parsing finished\n");
    debugVerbose(MAIN, "WEB_DIR = %s \n", scp_web_dir_);
    debugVerbose(MAIN, "CGI_DIR = %s \n", scp_cgi_dir_);
    debugVerbose(MAIN, "SECRET = %s \n", scp_secret_);
    debugVerbose(MAIN, "CGI_TIMEOUT = %d \n", si_cgi_timeout_);
    
    
    debugVerbose(MAIN, "Switching stdin to non_blocking mode\n");
    if(setNonblocking(STDIN_FILENO))
    {
        debug(MAIN, "Switching stdin to non_blocking mode failed!\n");
        secAbort();
    }
    
    char* cp_header = retrieveHeader(STDIN_FILENO, STDIN_TIMEOUT);
    if(cp_header == NULL)
    {
        debug(MAIN,"STDIN has to talk to use! We don't like DoS\n");
        secExit(STATUS_CANCEL);
    }
    
    http_norm *hnp_info = normalizeHttp(cp_header, FALSE);
    
    
    debugVerbose(MAIN, "Normalize finished \n");
    parse(hnp_info);
    debugVerbose(MAIN, "Parsing finished \n"); 
    
    
    if (mapRequestPath(&cp_mapped_path, &b_static) == FALSE)
    {
        secExit(STATUS_NOT_FOUND);
    }
    
    if (checkRequestPath(cp_mapped_path) == FALSE)
    {
        secExit(STATUS_NOT_FOUND);
    }
    
    cp_search_path_root = b_static ? scp_web_dir_ : scp_cgi_dir_;
    
    if (searchForHTDigestFile(cp_mapped_path, cp_search_path_root, &b_digest_file_available, 
        &cp_path_to_htdigest_file) == EXIT_FAILURE)
    {
        
        //  We found two .htdigest Files in the path! File is protected!
        secExit(STATUS_FORBIDDEN);
    }
    
    if (b_digest_file_available)
    {
        b_authenticated = authenticate(cp_path_to_htdigest_file);
    }
    
    
    if(b_authenticated == TRUE || b_digest_file_available == FALSE)
    {
        if(b_static == TRUE)
        {
            processStaticFile(cp_mapped_path);
        }
        else
        {
            setupEnvVarList(scp_web_dir_, cp_mapped_path, hnp_info, b_authenticated);
            processCGIScript(cp_mapped_path);
        }
    }
    
    secExit(STATUS_OK);
    return EXIT_SUCCESS;
}
Beispiel #26
0
static void do_epoll(int listenfd)
{
	int epollfd, sockfd;
	//ev用于注册事件,数组用于存储要处理的事件
	struct epoll_event ev, events[LISTENQ];
	struct sockaddr_in clien_addr;
	int fd_numb;
	int i, rw_size;
	char buf[MAXSIZE];
	int clilen;
	pthread_t pid;

	//创建一个描述符
	epollfd = epoll_create(LISTENQ);
	//添加监听描述符事件
	//EPOLLIN:表示对应的文件描述符可读; EPOLLIN:设置ET工作模式
	ev.events = EPOLLIN | EPOLLET;
	ev.data.fd = listenfd;
	//EPOLL_CTL_ADD:注册listenfd到epollfd中
	epoll_ctl(epollfd, EPOLL_CTL_ADD, listenfd, &ev);

	while(1)
	{
		//获取已经准备好的描述符事件
		//第3个参数不能大于epoll_create的参数, -1:超时时间, -1表示永久阻塞
		fd_numb = epoll_wait(epollfd, events, LISTENQ, -1);
		//printf("收到连接请求数:%d\n", fd_numb);

		//处理事件
		for(i=0; i<fd_numb; i++)
		{
			//检测到用户连接
			if(events[i].data.fd == listenfd){
				clilen = sizeof(clien_addr);
				sockfd = accept(listenfd, (struct sockaddr *)&clien_addr, &clilen );
				if(sockfd == -1){
					perror("accept error");
					exit(1);
				}
				//printf("accept a new client: %s:%d\n", inet_ntoa(clien_addr.sin_addr), ntohs(clien_addr.sin_port)/* clien_addr.sin_port*/ );

				setNonblocking(sockfd);
				//继续添加事件
				ev.data.fd = sockfd;
				ev.events = EPOLLIN | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_ADD, sockfd, &ev);
			}
			else if(events[i].events & EPOLLIN){
				//printf("创建了处理线程\n");
				pthread_create(&pid , NULL, (void *)handleThread, (void *)&sockfd);
			}
			/*
			else if(events[i].events & EPOLLIN){
				rw_size = epoll_read(sockfd, buf, MAXSIZE);
				//事件读改为写, EPOLL_CTL_MOD:修改已经注册的监听事件
				ev.data.fd = sockfd;
				handleThread,ev.events = EPOLLOUT | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_MOD, sockfd, &ev);
			}
			else if(events[i].events & EPOLLOUT){
				//rw_size = write(sockfd, buf, rw_size);
				epoll_write(sockfd, buf);

				//事件写改读
				ev.data.fd = events[i].data.fd;
				ev.events = EPOLLIN | EPOLLET;
				epoll_ctl(epollfd, EPOLL_CTL_MOD, events[i].data.fd, &ev);
			}*/
		}

	}
	close(epollfd);
	free(events);

}
Beispiel #27
0
FdEventHandlerPtr
create_listener(char *address, int port,
                int (*handler)(int, FdEventHandlerPtr, AcceptRequestPtr),
                void *data)
{
    int fd, rc;
    int one = 1;
    int done;
    struct sockaddr_in addr;
#ifdef HAVE_IPv6
    int inet6 = 1;
    struct sockaddr_in6 addr6;
#else
    int inet6 = 0;
#endif

    if(inet6 && address) {
        struct in_addr buf;
        rc = inet_aton(address, &buf);
        if(rc == 1)
            inet6 = 0;
    }
    fd = -1;
    errno = EAFNOSUPPORT;

#ifdef HAVE_IPv6
    if(inet6) {
        fd = socket(PF_INET6, SOCK_STREAM, 0);
    }
#endif

    if(fd < 0 && (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT)) {
        inet6 = 0;
        fd = socket(PF_INET, SOCK_STREAM, 0);
    }

    if(fd < 0) {
        done = (*handler)(-errno, NULL, NULL);
        assert(done);
        return NULL;
    }

    rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
    if(rc < 0) do_log_error(L_WARN, errno, "Couldn't set SO_REUSEADDR");

    if(inet6) {
#ifdef HAVE_IPv6
        rc = setV6only(fd, 0);
        if(rc < 0)
            /* Reportedly OpenBSD returns an error for that.  So only
               log it as a debugging message. */
            do_log_error(D_CLIENT_CONN, errno, "Couldn't reset IPV6_V6ONLY");

        memset(&addr6, 0, sizeof(addr6));
        rc = inet_pton(AF_INET6, address, &addr6.sin6_addr);
        if(rc != 1) {
            done = (*handler)(rc == 0 ? -ESYNTAX : -errno, NULL, NULL);
            assert(done);
            return NULL;
        }
        addr6.sin6_family = AF_INET6;
        addr6.sin6_port = htons(port);
        rc = bind(fd, (struct sockaddr*)&addr6, sizeof(addr6));
#else
        rc = -1;
        errno = EAFNOSUPPORT;
#endif
    } else {
        memset(&addr, 0, sizeof(addr));
        rc = inet_aton(address, &addr.sin_addr);
        if(rc != 1) {
            done = (*handler)(rc == 0 ? -ESYNTAX : -errno, NULL, NULL);
            assert(done);
            close(fd);
            return NULL;
        }
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        rc = bind(fd, (struct sockaddr*)&addr, sizeof(addr));
    }

    if(rc < 0) {
        do_log_error(L_ERROR, errno, "Couldn't bind");
        CLOSE(fd);
        done = (*handler)(-errno, NULL, NULL);
        assert(done);
        return NULL;
    }

    rc = setNonblocking(fd, 1);
    if(rc < 0) {
        do_log_error(L_ERROR, errno, "Couldn't set non blocking mode");
        CLOSE(fd);
        done = (*handler)(-errno, NULL, NULL);
        assert(done);
        return NULL;
    }
        
    rc = listen(fd, 1024);
    if(rc < 0) {
        do_log_error(L_ERROR, errno, "Couldn't listen");
        CLOSE(fd);
        done = (*handler)(-errno, NULL, NULL);
        assert(done);
        return NULL;
    }

    do_log(L_INFO, "Established listening socket on port %d.\n", port);

    return schedule_accept(fd, handler, data);
}
Beispiel #28
0
int main(int argc , char **argv)
{
	int i, listenfd, connfd, sockfd, epfd, nfds;

	ssize_t n, ret;
		
	char buf[MAX_LINE];

	socklen_t clilen;

	struct sockaddr_in servaddr , cliaddr;

	/*声明epoll_event结构体变量,ev用于注册事件,数组用于回传要处理的事件*/
	struct epoll_event ev, events[20];

	/*(1) 得到监听描述符*/
	listenfd = socket(AF_INET , SOCK_STREAM , 0);
	setNonblocking(listenfd);

	/*生成用于处理accept的epoll专用文件描述符*/	
	epfd = epoll_create(CONNECT_SIZE);
	/*设置监听描述符*/
	ev.data.fd = listenfd;
	/*设置处理事件类型*/
	ev.events = EPOLLIN | EPOLLET;
	/*注册事件*/
	epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev);		

	/*(2) 绑定套接字*/	
	bzero(&servaddr , sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(PORT);

	bind(listenfd , (struct sockaddr *)&servaddr , sizeof(servaddr));

	/*(3) 监听*/
	listen(listenfd , LISTENQ);

	/*(4) 进入服务器接收请求死循环*/
	while(1)
	{
		/*等待事件发生*/
		nfds = epoll_wait(epfd , events , CONNECT_SIZE , -1);
		if(nfds <= 0)
			continue;
	
		printf("nfds = %d\n" , nfds);
		/*处理发生的事件*/
		for(i=0 ; i<nfds ; ++i)
		{
			/*检测到用户链接*/
			if(events[i].data.fd == listenfd)
			{	
				/*接收客户端的请求*/
				clilen = sizeof(cliaddr);

				if((connfd = accept(listenfd , (struct sockaddr *)&cliaddr , &clilen)) < 0)
				{
					perror("accept error.\n");
					exit(1);
				}//if		

				printf("accpet a new client: %s:%d\n", inet_ntoa(cliaddr.sin_addr) , cliaddr.sin_port);
			
				/*设置为非阻塞*/
				setNonblocking(connfd);
				ev.data.fd = connfd;
				ev.events = EPOLLIN | EPOLLET;
				epoll_ctl(epfd , EPOLL_CTL_ADD , connfd , &ev);
			}//if
			/*如果是已链接用户,并且收到数据,进行读入*/
			else if(events[i].events & EPOLLIN){

				if((sockfd = events[i].data.fd) < 0)
					continue;
				bzero(buf , MAX_LINE);
				printf("reading the socket~~~\n");
				if((n = read(sockfd , buf , MAX_LINE)) <= 0)
				{
					close(sockfd);
					events[i].data.fd = -1;
				}//if
				else{
					buf[n] = '\0';
					printf("clint[%d] send message: %s\n", i , buf);
				
					/*设置用于注册写操作文件描述符和事件*/
					ev.data.fd = sockfd;
					ev.events = EPOLLOUT| EPOLLET;	
					epoll_ctl(epfd , EPOLL_CTL_MOD , sockfd , &ev);			
				}//else											
			}//else
			else if(events[i].events & EPOLLOUT)
			{
				if((sockfd = events[i].data.fd) < 0)
				continue;
				if((ret = write(sockfd , buf , n)) != n)	
				{
					printf("error writing to the sockfd!\n");
					break;
				}//if
				/*设置用于读的文件描述符和事件*/
				ev.data.fd = sockfd;
				ev.events = EPOLLIN | EPOLLET;
				/*修改*/
				epoll_ctl(epfd , EPOLL_CTL_MOD , sockfd , &ev);				
			}//else
		}//for
	}//while
	free(events);
	close(epfd);
	exit(0);
}