Ejemplo n.º 1
0
static int
set_ready_fd(int fd, ofp_fd_set *fd_set, int(*is_ready)(int fd))
{
	if (OFP_FD_ISSET(fd, fd_set) && is_ready(fd))
		return 1;

	OFP_FD_CLR(fd, fd_set);
	return 0;
}
Ejemplo n.º 2
0
Archivo: httpd.c Proyecto: fboudra/ofp
static void *webserver(void *arg)
{
	int serv_fd, tmp_fd, nfds;
	unsigned int alen;
	struct ofp_sockaddr_in my_addr, caller;
	ofp_fd_set read_fd;

	(void)arg;

	OFP_INFO("HTTP thread started");

	if (ofp_init_local()) {
		OFP_ERR("Error: OFP local init failed.\n");
		return NULL;
	}
	sleep(1);

	myaddr = ofp_port_get_ipv4_addr(0, 0, OFP_PORTCONF_IP_TYPE_IP_ADDR);

	if ((serv_fd = ofp_socket(OFP_AF_INET, OFP_SOCK_STREAM, OFP_IPPROTO_TCP)) < 0) {
		OFP_ERR("ofp_socket failed");
		perror("serv socket");
		return NULL;
	}

	memset(&my_addr, 0, sizeof(my_addr));
	my_addr.sin_family = OFP_AF_INET;
	my_addr.sin_port = odp_cpu_to_be_16(2048);
	my_addr.sin_addr.s_addr = myaddr;
	my_addr.sin_len = sizeof(my_addr);

	if (ofp_bind(serv_fd, (struct ofp_sockaddr *)&my_addr,
		       sizeof(struct ofp_sockaddr)) < 0) {
		OFP_ERR("Cannot bind http socket (%s)!", ofp_strerror(ofp_errno));
		return 0;
	}

	ofp_listen(serv_fd, 10);
	OFP_FD_ZERO(&read_fd);
	nfds = serv_fd;

	for ( ; ; )
	{
		int r, i;
		static char buf[1024];
		struct ofp_timeval timeout;

		timeout.tv_sec = 0;
		timeout.tv_usec = 200000;

		OFP_FD_SET(serv_fd, &read_fd);
		monitor_connections(&read_fd);
		r = ofp_select(nfds + 1, &read_fd, NULL, NULL, &timeout);
		if (r <= 0)
			continue;

		if (OFP_FD_ISSET(serv_fd, &read_fd)) {
			alen = sizeof(caller);
			if ((tmp_fd = ofp_accept(serv_fd,
						   (struct ofp_sockaddr *)&caller,
						   &alen)) > 0) {
				OFP_INFO("accept fd=%d", tmp_fd);

				for (i = 0; i < NUM_CONNECTIONS; i++)
					if (connections[i].fd == 0)
						break;

				if (i >= NUM_CONNECTIONS) {
					OFP_ERR("Node cannot accept new connections!");
					ofp_close(tmp_fd);
					continue;
				}

#if 0
				struct ofp_linger so_linger;
				so_linger.l_onoff = 1;
				so_linger.l_linger = 0;
				int r1 = ofp_setsockopt(tmp_fd,
							  OFP_SOL_SOCKET,
							  OFP_SO_LINGER,
							  &so_linger,
							  sizeof so_linger);
				if (r1) OFP_ERR("SO_LINGER failed!");
#endif
				struct ofp_timeval tv;
				tv.tv_sec = 3;
				tv.tv_usec = 0;
				int r2 = ofp_setsockopt(tmp_fd,
							  OFP_SOL_SOCKET,
							  OFP_SO_SNDTIMEO,
							  &tv,
							  sizeof tv);
				if (r2) OFP_ERR("SO_SNDTIMEO failed!");

				connections[i].fd = tmp_fd;
				connections[i].addr = caller.sin_addr.s_addr;
				connections[i].closed = FALSE;

				if (tmp_fd > nfds)
				        nfds = tmp_fd;
			}
		}

		for (i = 0; i < NUM_CONNECTIONS; i++) {
			if (connections[i].fd == 0)
				continue;

			if (!(OFP_FD_ISSET(connections[i].fd, &read_fd)))
				continue;

			r = ofp_recv(connections[i].fd, buf, sizeof(buf)-1, 0);
			if (r > 0) {
				buf[r] = 0;
				OFP_INFO("recv data: %s", buf);

				if (!strncmp(buf, "GET", 3))
					analyze_http(buf, connections[i].fd);
				else
					OFP_INFO("Not a HTTP GET request");

				OFP_INFO("closing %d\n", connections[i].fd);
				OFP_FD_CLR(connections[i].fd, &read_fd);
				while (ofp_close(connections[i].fd) < 0) {
					OFP_ERR("ofp_close failed, fd=%d err='%s'",
						connections[i].fd,
						ofp_strerror(ofp_errno));
					sleep(1);
				}
				OFP_INFO("closed fd=%d", connections[i].fd);
				connections[i].fd = 0;
			} else if (r == 0) {
				if (connections[i].post) {
					OFP_INFO("File download finished");
					fclose(connections[i].post);
					connections[i].post = NULL;
				}
				ofp_close(connections[i].fd);
				OFP_FD_CLR(connections[i].fd, &read_fd);
				connections[i].fd = 0;
			}
		}
	}

	OFP_INFO("httpd exiting");
	return NULL;
}