static int webserver(void *arg) { int serv_fd, tmp_fd; struct ofp_sockaddr_in my_addr; (void)arg; OFP_INFO("HTTP thread started"); if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return -1; } 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 -1; } 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 -1; } ofp_listen(serv_fd, 10); #ifndef USE_EPOLL OFP_INFO("Using ofp_select"); ofp_fd_set read_fd; OFP_FD_ZERO(&read_fd); int nfds = serv_fd; #else OFP_INFO("Using ofp_epoll"); int epfd = ofp_epoll_create(1); struct ofp_epoll_event e = { OFP_EPOLLIN, { .fd = serv_fd } };
static int handle_connection(int i) { int fd, r; static char buf[1024]; if (connections[i].fd == 0) return 0; fd = connections[i].fd; r = ofp_recv(connections[i].fd, buf, sizeof(buf)-1, 0); if (r < 0) return 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 an HTTP GET request"); OFP_INFO("closing %d\n", connections[i].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); connections[i].fd = 0; } return fd; }
/* Sending function with some debugging. */ static int mysend(int s, char *p, int len) { int n; while (len > 0) { n = ofp_send(s, p, len, 0); if (n < 0) { OFP_ERR("ofp_send failed n=%d, err='%s'", n, ofp_strerror(ofp_errno)); return n; } len -= n; p += n; if (len) { OFP_WARN("Only %d bytes sent", n); } } return len; }
static void *mcasttest(void *arg) { int fd; struct ofp_sockaddr_in my_addr; struct ofp_ip_mreq mreq; (void)arg; logprint("Multicast thread started\n"); if (odp_init_local(ODP_THREAD_CONTROL)) { OFP_ERR("Error: ODP local init failed.\n"); return NULL; } if (ofp_init_local()) { OFP_ERR("Error: OFP local init failed.\n"); return NULL; } sleep(1); while (myaddr == 0) { myaddr = ofp_port_get_ipv4_addr(0, 0, OFP_PORTCONF_IP_TYPE_IP_ADDR); sleep(1); } if ((fd = ofp_socket(OFP_AF_INET, OFP_SOCK_DGRAM, OFP_IPPROTO_UDP)) < 0) { perror("socket"); logprint("Cannot open socket!\n"); 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 = 0; my_addr.sin_len = sizeof(my_addr); if (ofp_bind(fd, (struct ofp_sockaddr *)&my_addr, sizeof(struct ofp_sockaddr)) < 0) { logprint("Cannot bind socket (%s)!\n", ofp_strerror(ofp_errno)); return NULL; } memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = IP4(234,5,5,5); mreq.imr_interface.s_addr = myaddr; if (ofp_setsockopt(fd, OFP_IPPROTO_IP, OFP_IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { perror("setsockopt"); } memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = IP4(234,7,7,7); mreq.imr_interface.s_addr = myaddr; if (ofp_setsockopt(fd, OFP_IPPROTO_IP, OFP_IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { perror("setsockopt"); } for (;;) { char buf[100]; int len = sizeof(buf); struct ofp_sockaddr_in addr = {0}; ofp_socklen_t addr_len = 0; len = ofp_recvfrom(fd, buf, len, 0, (struct ofp_sockaddr *)&addr, &addr_len); if (len == -1) { OFP_ERR("Faild to rcv data(errno = %d)\n", ofp_errno); continue; } buf[len] = 0; OFP_INFO("Data (%s, len = %d) was received.\n", buf, len); if (addr_len != sizeof(addr)) { OFP_ERR("Faild to rcv source address: %d (errno = %d)\n", addr_len, ofp_errno); continue; } if (strstr(buf, "add")) { OFP_INFO("Add membership to 234.7.7.7\n"); memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = IP4(234,7,7,7); mreq.imr_interface.s_addr = myaddr; if (ofp_setsockopt(fd, OFP_IPPROTO_IP, OFP_IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { perror("setsockopt"); } } else if (strstr(buf, "drop")) { OFP_INFO("Drop membership from 234.7.7.7\n"); memset(&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = IP4(234,7,7,7); mreq.imr_interface.s_addr = myaddr; if (ofp_setsockopt(fd, OFP_IPPROTO_IP, OFP_IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) == -1) { perror("setsockopt"); } } else if (strstr(buf, "quit")) { exit(0); } OFP_INFO("Data was received from address 0x%x, port = %d.\n", odp_be_to_cpu_32(addr.sin_addr.s_addr), odp_be_to_cpu_16(addr.sin_port)); sprintf(buf, "%d bytes\n", len); if (ofp_sendto(fd, buf, strlen(buf), 0, (struct ofp_sockaddr *)&addr, sizeof(addr)) == -1) { OFP_ERR("Faild to send data (errno = %d)\n", ofp_errno); } } logprint("mcast exit\n"); return NULL; }
static void test_strerrno(void) { CU_ASSERT_STRING_EQUAL(ofp_strerror(OFP_EALREADY), "Operation already in progress"); CU_ASSERT_STRING_EQUAL(ofp_strerror(OFP_ELAST+1), ""); }
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; }