/* * libioth: choose your networking library as a plugin at run time. * test program: server * * Copyright (C) 2020-2022 Renzo Davoli <renzo@cs.unibo.it> * VirtualSquare team. * * this test program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; If not, see <http://www.gnu.org/licenses/>. */ #define SPDX_LICENSE "SPDX-License-Identifier: GPL-2.0-or-later" #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <stdint.h> #include <sys/socket.h> #include <sys/types.h> #include <sys/wait.h> #include <netinet/in.h> #include <pthread.h> #include <ioth.h> void *handle (void *arg) { int connfd = (uintptr_t) arg; int n; char buf[BUFSIZ]; printf("new conn %d tid %d\n", connfd, gettid()); for(;;) { if ((n = ioth_recv(connfd, buf, BUFSIZ, 0)) <= 0) break; printf("tid %d GOT: %*.*s",gettid(),n,n,buf); ioth_send(connfd, buf, n, 0); } printf("close conn %d tid %d\n", connfd, gettid()); ioth_close(connfd); return NULL; } void server(struct ioth *mystack) { struct sockaddr_in servaddr; int fd, connfd; fd = ioth_msocket(mystack, AF_INET, SOCK_STREAM, 0); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(5000); servaddr.sin_addr.s_addr = 0; if (ioth_bind(fd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) exit(1); ioth_listen (fd, 5); for ( ; ; ) { pthread_t pt; connfd = ioth_accept (fd, NULL, NULL); if (connfd < 0) break; pthread_create(&pt, NULL, handle, (void *) (uintptr_t)connfd); pthread_detach(pt); } ioth_close(fd); } struct ioth *net_setup(const char **args) { struct ioth *mystack; uint8_t ipv4addr[] = {192,168,250,50}; uint8_t ipv4gw[] = {192,168,250,1}; int ifindex; mystack = ioth_newstackv(args[0], args+1); if (mystack != NULL) { ifindex = ioth_if_nametoindex(mystack, "vde0"); if (ifindex < 0) perror("nametoindex"); else { if (ioth_linksetupdown(mystack, ifindex, 1) < 0) perror("link up"); if (ioth_ipaddr_add(mystack, AF_INET, ipv4addr, 24, ifindex) < 0) perror("addr ipv4"); if (ioth_iproute_add(mystack, AF_INET, NULL, 0, ipv4gw, 0) < 0) perror("route ipv4"); } } return mystack; } int main(int argc, const char *argv[]) { ioth_set_license(SPDX_LICENSE); if (argc < 2) { fprintf(stderr, "Usage:\n\n\t%s stack [ vnl vnl ]\n\n", basename(argv[0])); exit(1); } else { struct ioth *mystack = net_setup(argv+1); // printf("%p\n", mystack); if (mystack) { server(mystack); ioth_delstack(mystack); } else perror("net_setup"); } }