1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdint.h> 4 #include <string.h> 5 #include <strings.h> 6 #include <sys/types.h> 7 #include <sys/socket.h> 8 #include <arpa/inet.h> 9 #include <errno.h> 10 #include <assert.h> 11 12 #include "ff_config.h" 13 #include "ff_api.h" 14 15 #define MAX_EVENTS 512 16 17 /* kevent set */ 18 struct kevent kevSet; 19 /* events */ 20 struct kevent events[MAX_EVENTS]; 21 /* kq */ 22 int kq; 23 int sockfd; 24 #ifdef INET6 25 int sockfd6; 26 #endif 27 28 char html[] = 29 "HTTP/1.1 200 OK\r\n" 30 "Server: F-Stack\r\n" 31 "Date: Sat, 25 Feb 2017 09:26:33 GMT\r\n" 32 "Content-Type: text/html\r\n" 33 "Content-Length: 438\r\n" 34 "Last-Modified: Tue, 21 Feb 2017 09:44:03 GMT\r\n" 35 "Connection: keep-alive\r\n" 36 "Accept-Ranges: bytes\r\n" 37 "\r\n" 38 "<!DOCTYPE html>\r\n" 39 "<html>\r\n" 40 "<head>\r\n" 41 "<title>Welcome to F-Stack!</title>\r\n" 42 "<style>\r\n" 43 " body { \r\n" 44 " width: 35em;\r\n" 45 " margin: 0 auto; \r\n" 46 " font-family: Tahoma, Verdana, Arial, sans-serif;\r\n" 47 " }\r\n" 48 "</style>\r\n" 49 "</head>\r\n" 50 "<body>\r\n" 51 "<h1>Welcome to F-Stack!</h1>\r\n" 52 "\r\n" 53 "<p>For online documentation and support please refer to\r\n" 54 "<a href=\"http://F-Stack.org/\">F-Stack.org</a>.<br/>\r\n" 55 "\r\n" 56 "<p><em>Thank you for using F-Stack.</em></p>\r\n" 57 "</body>\r\n" 58 "</html>"; 59 60 int loop(void *arg) 61 { 62 /* Wait for events to happen */ 63 unsigned nevents = ff_kevent(kq, NULL, 0, events, MAX_EVENTS, NULL); 64 unsigned i; 65 66 for (i = 0; i < nevents; ++i) { 67 struct kevent event = events[i]; 68 int clientfd = (int)event.ident; 69 70 /* Handle disconnect */ 71 if (event.flags & EV_EOF) { 72 /* Simply close socket */ 73 ff_close(clientfd); 74 #ifdef INET6 75 } else if (clientfd == sockfd || clientfd == sockfd6) { 76 #else 77 } else if (clientfd == sockfd) { 78 #endif 79 int available = (int)event.data; 80 do { 81 int nclientfd = ff_accept(clientfd, NULL, NULL); 82 if (nclientfd < 0) { 83 printf("ff_accept failed:%d, %s\n", errno, 84 strerror(errno)); 85 break; 86 } 87 88 /* Add to event list */ 89 EV_SET(&kevSet, nclientfd, EVFILT_READ, EV_ADD, 0, 0, NULL); 90 91 if(ff_kevent(kq, &kevSet, 1, NULL, 0, NULL) < 0) { 92 printf("ff_kevent error:%d, %s\n", errno, 93 strerror(errno)); 94 return -1; 95 } 96 97 available--; 98 } while (available); 99 } else if (event.filter == EVFILT_READ) { 100 char buf[256]; 101 size_t readlen = ff_read(clientfd, buf, sizeof(buf)); 102 103 ff_write(clientfd, html, sizeof(html) - 1); 104 } else { 105 printf("unknown event: %8.8X\n", event.flags); 106 } 107 } 108 } 109 110 int main(int argc, char * argv[]) 111 { 112 ff_init(argc, argv); 113 114 assert((kq = ff_kqueue()) > 0); 115 116 sockfd = ff_socket(AF_INET, SOCK_STREAM, 0); 117 if (sockfd < 0) { 118 printf("ff_socket failed, sockfd:%d, errno:%d, %s\n", sockfd, errno, strerror(errno)); 119 exit(1); 120 } 121 122 struct sockaddr_in my_addr; 123 bzero(&my_addr, sizeof(my_addr)); 124 my_addr.sin_family = AF_INET; 125 my_addr.sin_port = htons(80); 126 my_addr.sin_addr.s_addr = htonl(INADDR_ANY); 127 128 int ret = ff_bind(sockfd, (struct linux_sockaddr *)&my_addr, sizeof(my_addr)); 129 if (ret < 0) { 130 printf("ff_bind failed, sockfd:%d, errno:%d, %s\n", sockfd, errno, strerror(errno)); 131 exit(1); 132 } 133 134 ret = ff_listen(sockfd, MAX_EVENTS); 135 if (ret < 0) { 136 printf("ff_listen failed, sockfd:%d, errno:%d, %s\n", sockfd, errno, strerror(errno)); 137 exit(1); 138 } 139 140 EV_SET(&kevSet, sockfd, EVFILT_READ, EV_ADD, 0, MAX_EVENTS, NULL); 141 /* Update kqueue */ 142 ff_kevent(kq, &kevSet, 1, NULL, 0, NULL); 143 144 #ifdef INET6 145 sockfd6 = ff_socket(AF_INET6, SOCK_STREAM, 0); 146 if (sockfd6 < 0) { 147 printf("ff_socket failed, sockfd6:%d, errno:%d, %s\n", sockfd6, errno, strerror(errno)); 148 exit(1); 149 } 150 151 struct sockaddr_in6 my_addr6; 152 bzero(&my_addr6, sizeof(my_addr6)); 153 my_addr6.sin6_family = AF_INET6; 154 my_addr6.sin6_port = htons(80); 155 my_addr6.sin6_addr = in6addr_any; 156 157 ret = ff_bind(sockfd6, (struct linux_sockaddr *)&my_addr6, sizeof(my_addr6)); 158 if (ret < 0) { 159 printf("ff_bind failed, sockfd6:%d, errno:%d, %s\n", sockfd6, errno, strerror(errno)); 160 exit(1); 161 } 162 163 ret = ff_listen(sockfd6, MAX_EVENTS); 164 if (ret < 0) { 165 printf("ff_listen failed, sockfd6:%d, errno:%d, %s\n", sockfd6, errno, strerror(errno)); 166 exit(1); 167 } 168 169 EV_SET(&kevSet, sockfd6, EVFILT_READ, EV_ADD, 0, MAX_EVENTS, NULL); 170 ff_kevent(kq, &kevSet, 1, NULL, 0, NULL); 171 #endif 172 173 ff_run(loop, NULL); 174 return 0; 175 } 176