summaryrefslogtreecommitdiffstats
path: root/demo/nginx_proxy
diff options
context:
space:
mode:
authoryalei wang <wylandrea@gmail.com>2018-12-27 02:28:55 +0000
committerGerrit Code Review <gerrit@fd.io>2018-12-27 02:28:55 +0000
commit82b8efb032cffb13e92d5f7f3d30d53ec1c93663 (patch)
treea9dd82bd6b65335be9b736e5f8ac41a00611cbea /demo/nginx_proxy
parent642adb4b3f0be545c96a3cf929f2ede8a7be5b2d (diff)
parent224195a2c6144aa2a2c6ca06794115b3c654469d (diff)
Merge "Feat: Nginx demo with rsocket and kernel"
Diffstat (limited to 'demo/nginx_proxy')
-rw-r--r--demo/nginx_proxy/README.md11
-rw-r--r--demo/nginx_proxy/demo-3/NGINX_with_DMM_Demo.md26
-rw-r--r--demo/nginx_proxy/demo-3/proxy_nginx.conf81
-rw-r--r--demo/nginx_proxy/demo-3/rd_config.json23
-rw-r--r--demo/nginx_proxy/demo-3/rsocket.pngbin0 -> 10614 bytes
-rw-r--r--demo/nginx_proxy/demo-3/server/index.html31
-rw-r--r--demo/nginx_proxy/demo-3/server/test.c320
7 files changed, 489 insertions, 3 deletions
diff --git a/demo/nginx_proxy/README.md b/demo/nginx_proxy/README.md
index b8a9705..4085cc9 100644
--- a/demo/nginx_proxy/README.md
+++ b/demo/nginx_proxy/README.md
@@ -13,7 +13,12 @@ Procedures and details of how to run this demo is inside each demo directory.
This demo use NGINX as a reverse proxy server. The server uses lwip as client facing stack and kernel tcp/ip
stack as upstream server facing stack.
-##demo-2
+##demo-2
-This demo NGINX as a reverse proxy server. The server uses lwip as client facing stack and kernel tcp/ip stack
-as upstream server facing stack for UDP, vpp-hoststack for another updtream server facing stack for TCP. \ No newline at end of file
+This demo NGINX as a reverse proxy server. The server uses lwip as client facing stack and kernel tcp/ip stack
+as upstream server facing stack for UDP, vpp-hoststack for another updtream server facing stack for TCP.
+
+##demo-3
+
+This demo NGINX as a reverse proxy server. The server uses kernel tcp/ip as client facing stack and rsocket
+stack as upstream server facing stack.
diff --git a/demo/nginx_proxy/demo-3/NGINX_with_DMM_Demo.md b/demo/nginx_proxy/demo-3/NGINX_with_DMM_Demo.md
new file mode 100644
index 0000000..6deb348
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/NGINX_with_DMM_Demo.md
@@ -0,0 +1,26 @@
+# Demo: NGINX working with multi-stack using DMM
+
+![image](rsocket.png)
+
+
+
+In above diagram NGINX box in the middle is working as reverse proxy.
+One of the NIC ( client facing) is using kernel tcp/ip stack whereas the
+other NIC is connected to upstream server using rsocket tcp/ip stack.
+
+you can use test.c to compile a server depend on libnStackAPI.so. It bind the
+port 8888 by default and you can change it to other port. Then copy the
+module_config.json rd_config.json to the folder of server. Then you can start the
+server as follow:
+./server 162.128.1.16
+
+####More Information:
+https://wiki.fd.io/view/DMM
+https://www.nginx.com/blog/ip-transparency-direct-server-return-nginx-plus-transparent-proxy/
+
+
+
+
+
+
+
diff --git a/demo/nginx_proxy/demo-3/proxy_nginx.conf b/demo/nginx_proxy/demo-3/proxy_nginx.conf
new file mode 100644
index 0000000..fb085ac
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/proxy_nginx.conf
@@ -0,0 +1,81 @@
+user root;
+worker_processes 1;
+daemon off;
+#error_log logs/error.log;
+#error_log logs/error.log notice;
+#error_log logs/error.log info;
+
+#pid logs/nginx.pid;
+
+
+events {
+ worker_connections 1024;
+}
+
+
+http {
+ include mime.types;
+ default_type application/octet-stream;
+
+ #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
+ # '$status $body_bytes_sent "$http_referer" '
+ # '"$http_user_agent" "$http_x_forwarded_for"';
+
+ #access_log logs/access.log main;
+
+ sendfile on;
+ #tcp_nopush on;
+
+ #keepalive_timeout 0;
+ keepalive_timeout 65;
+
+ #gzip on;
+
+ server {
+ listen 192.168.131.181:80 default_server;
+ server_name 192.168.131.181;
+
+ location / {
+ proxy_bind 192.168.21.181;
+ proxy_pass http://192.168.21.180:8888;
+ proxy_set_header X-Real-IP $remote_addr;
+ sendfile off;
+ proxy_buffering off;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ }
+
+ #error_page 404 /404.html;
+
+ # redirect server error pages to the static page /50x.html
+ #
+ error_page 500 502 503 504 /50x.html;
+ location = /50x.html {
+ root html;
+ }
+
+ # proxy the PHP scripts to Apache listening on 127.0.0.1:80
+ #
+ #location ~ \.php$ {
+ # proxy_pass http://127.0.0.1;
+ #}
+
+ # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
+ #
+ #location ~ \.php$ {
+ # root html;
+ # fastcgi_pass 127.0.0.1:9000;
+ # fastcgi_index index.php;
+ # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
+ # include fastcgi_params;
+ #}
+
+ # deny access to .htaccess files, if Apache's document root
+ # concurs with nginx's one
+ #
+ #location ~ /\.ht {
+ # deny all;
+ #}
+ }
+
+
+}
diff --git a/demo/nginx_proxy/demo-3/rd_config.json b/demo/nginx_proxy/demo-3/rd_config.json
new file mode 100644
index 0000000..51fa4a5
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/rd_config.json
@@ -0,0 +1,23 @@
+{
+ "ip_route": [
+ {
+ "subnet": "192.168.131.1/24",
+ "stack_name": "kernel",
+ },
+ {
+ "subnet": "192.168.21.1/24",
+ "stack_name": "rsocket",
+ },
+ ],
+ "prot_route": [
+ {
+ "proto_type": "1",
+ "stack_name": "rsocket",
+ },
+ {
+ "proto_type": "2",
+ "stack_name": "kernel",
+ }
+ ],
+}
+
diff --git a/demo/nginx_proxy/demo-3/rsocket.png b/demo/nginx_proxy/demo-3/rsocket.png
new file mode 100644
index 0000000..389ae19
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/rsocket.png
Binary files differ
diff --git a/demo/nginx_proxy/demo-3/server/index.html b/demo/nginx_proxy/demo-3/server/index.html
new file mode 100644
index 0000000..9ab30e1
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/server/index.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+
+<!--
+Copyright 2015 Google Inc.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<html>
+
+<head>
+ <title>Hello, world</title>
+ <link rel="stylesheet" href="/style.css">
+ <script src="/script.js"></script>
+</head>
+
+<body>
+ <h1>Hello, world</h1>
+
+ <button onclick="fetchMessage()">Fetch Message</button>
+ <p id="message">Click on the button to fetch the message.</p>
+</body>
+
+</html>
diff --git a/demo/nginx_proxy/demo-3/server/test.c b/demo/nginx_proxy/demo-3/server/test.c
new file mode 100644
index 0000000..9ffde09
--- /dev/null
+++ b/demo/nginx_proxy/demo-3/server/test.c
@@ -0,0 +1,320 @@
+/*
+ * httpd.c
+ *
+ * Copyright Adin Scannell 2011
+ *
+ * This code is intended for demo purposes only,
+ * please don't actually use it to do anything.
+ *
+ * To compile, use:
+ * gcc -o httpd httpd.c
+ * Then, create a file 'index.html' in the directory
+ * that you are running the server from. Put stuff in
+ * it.
+ * Then go to http://localhost:8888 and see the file.
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/sendfile.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <sys/mman.h>
+
+#define HTTP_BAD_REQUEST "HTTP/1.0 404 Not Found\r\n"
+#define HTTP_GOOD_REQUEST "HTTP/1.0 200\r\n"
+#define HTTP_CONTENT_TYPE "Content-Type: text/html\r\n"
+#define HTTP_CONTENT_LENGTH "Content-Length: %ld\r\n\r\n"
+#define MAX_REQUEST_SIZE 4096
+#define DEFAULT_PATH "index.html"
+
+#define DEBUG
+#ifdef DEBUG
+#define log(fmt, args...) fprintf(stderr, fmt "\n", ## args)
+#else
+#define log(fmt, args...)
+#endif
+
+int
+send_error (int fd)
+{
+ write (fd, HTTP_BAD_REQUEST, strlen (HTTP_BAD_REQUEST));
+ write (fd, HTTP_CONTENT_TYPE, strlen (HTTP_CONTENT_TYPE));
+ return 0;
+}
+
+int
+send_file (int fd, char *path)
+{
+ int iofd = open (path, O_RDONLY);
+
+ int ret = 0;
+ if (iofd < 0)
+ {
+ write (fd, HTTP_BAD_REQUEST, strlen (HTTP_BAD_REQUEST));
+ write (fd, HTTP_CONTENT_TYPE, strlen (HTTP_CONTENT_TYPE));
+ log ("error opening file");
+ }
+ else
+ {
+ char length[MAX_REQUEST_SIZE];
+ struct stat statinfo;
+ if (fstat (iofd, &statinfo) < 0)
+ {
+ /* Can't get the length. */
+ write (fd, HTTP_BAD_REQUEST, strlen (HTTP_BAD_REQUEST));
+ write (fd, HTTP_CONTENT_TYPE, strlen (HTTP_CONTENT_TYPE));
+ log ("error fetching size");
+ }
+ else
+ {
+ ret = write (fd, HTTP_GOOD_REQUEST, strlen (HTTP_GOOD_REQUEST));
+
+ log ("write HTTP_GOOD_REQUEST %s ret %d", HTTP_GOOD_REQUEST, ret);
+ ret = write (fd, HTTP_CONTENT_TYPE, strlen (HTTP_CONTENT_TYPE));
+ log ("write HTTP_CONTENT_TYPE %s ret %d", HTTP_CONTENT_TYPE, ret);
+ snprintf (length, MAX_REQUEST_SIZE,
+ HTTP_CONTENT_LENGTH, statinfo.st_size);
+
+ ret = write (fd, length, strlen (length));
+ log ("write %s ret %d", length, ret);
+
+#if 1
+#if 1
+ //char *source = NULL;
+ //source = malloc(sizeof(char) * (statinfo.st_size + 1));
+ void *file_addr = NULL;
+ file_addr =
+ mmap (NULL, statinfo.st_size, PROT_READ, MAP_PRIVATE, iofd, 0);
+
+ if (write (fd, file_addr, statinfo.st_size) < 0)
+ {
+ perror ("wyl new");
+ }
+
+#else
+// if( write(fd, length, strlen(length)) < 0 ||
+ if (sendfile (fd, iofd, NULL, statinfo.st_size) < 0)
+ {
+ /* Error sending the file. Nothing can be done. */
+ perror ("error writing file");
+ }
+#endif
+
+#endif
+ close (fd);
+ }
+
+ close (iofd);
+ }
+
+ return 0;
+}
+
+int
+process (int fd, char *header)
+{
+ char npath[MAX_REQUEST_SIZE];
+
+ char *eol = strchr (header, '\r');
+
+ /* Nuts to thread-safe, this demo uses it's own process :P */
+ char *method = strtok (header, " ");
+ char *path = strtok (NULL, " ");
+ char *http = strtok (NULL, " ");
+
+ if (eol != NULL)
+ {
+ *eol = '\0';
+ }
+
+ /* Debug output here, just in case anyone is watching. */
+ log (" * method = %s", method);
+ log (" * path = %s", path);
+ log (" * http = %s", http);
+
+ /* Ensure that we can process it. */
+ if (strcmp (method, "GET") ||
+ (strcmp (http, "HTTP/1.0") && strcmp (http, "HTTP/1.1")))
+ {
+ log ("bad request");
+ return send_error (fd);
+ }
+ else
+ {
+ if (path[0] == '/' && path[1] == '\0')
+ {
+ path = DEFAULT_PATH;
+ }
+ else if (path[0] == '/')
+ {
+ snprintf (npath, MAX_REQUEST_SIZE, ".%s", path);
+ path = npath;
+ }
+ log ("sending %s to %d", path, fd);
+ return send_file (fd, path);
+ }
+}
+
+int
+service (int fd)
+{
+ char buffer[MAX_REQUEST_SIZE];
+ int readbytes = 0, scanned = 0;
+
+ /* Attempt to read a chunk of bytes, but not process forever. */
+ while (readbytes < (MAX_REQUEST_SIZE - 1))
+ {
+ log ("read from %d", fd);
+ int cur =
+ read (fd, &(buffer[readbytes]), (MAX_REQUEST_SIZE - 1) - readbytes);
+ if (cur < 0)
+ {
+ perror ("read failed");
+ return -1;
+ }
+ else
+ {
+ buffer[readbytes + cur + 1] = '\0';
+ readbytes += cur;
+ }
+
+ /* Check for the \n\n found at the end of the header. */
+ for (; scanned < readbytes - 3; scanned++)
+ {
+ if (buffer[scanned] == '\r' && buffer[scanned + 1] == '\n' &&
+ buffer[scanned + 2] == '\r' && buffer[scanned + 3] == '\n')
+ {
+ buffer[scanned] = '\0';
+ return process (fd, buffer);
+ }
+ }
+ }
+
+ /* Failed to find the end of the header. */
+ log ("header too long");
+ return -1;
+}
+
+int
+main (int argc, char *argv[])
+{
+
+ struct sockaddr_in servaddr;
+ int serversock = socket (AF_INET, SOCK_STREAM, 0);
+ int on = 1;
+
+ if (NULL == argv[1])
+ {
+ log ("please set the ip argument");
+ return 1;
+ }
+
+ /* Create socket. */
+ if (serversock < 0)
+ {
+ perror ("error creating socket");
+ return 1;
+ }
+
+ /* Tweak it for reuse. Not necessary for fork, just useful *
+ * when one is killing and running this server a few times. */
+ if (setsockopt (serversock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof (on)) < 0)
+ {
+ perror ("unable to tweak socket options");
+ }
+
+ /* Bind to port 8888. */
+ memset (&servaddr, 0, sizeof (servaddr));
+ servaddr.sin_family = AF_INET;
+ //servaddr.sin_addr.s_addr = inet_addr("192.168.21.180");
+ servaddr.sin_addr.s_addr = inet_addr (argv[1]);
+ servaddr.sin_port = htons (8888);
+ if (bind (serversock, (struct sockaddr *) &servaddr, sizeof (servaddr)) < 0)
+ {
+ perror ("couldn't bind to given address");
+ return 1;
+ }
+ log ("bound to %s:8888", argv[1]);
+
+ /* Start listening, queue size 10. */
+ if (listen (serversock, 10) < 0)
+ {
+ perror ("listen failed");
+ return 1;
+ }
+ log ("listening");
+
+ /* Enter the service loop. */
+ while (1)
+ {
+ int clientsock, pid, childstatus;
+ log ("waiting for next request");
+
+ /* Grab the next request. */
+ clientsock = accept (serversock, NULL, NULL);
+ if (clientsock < 0)
+ {
+ perror ("accept failed");
+ break;
+ }
+ log ("accepted connection %d from %d, forking ", clientsock,
+ serversock);
+
+ /* Fork off a handler. */
+ //pid = fork();
+ pid = 0;
+ if (pid < 0)
+ {
+ perror ("fork failed");
+ close (clientsock);
+ continue;
+ }
+ else if (pid > 0)
+ {
+ close (clientsock);
+ }
+ else
+ {
+ //close(serversock);
+ log ("servicing connection (as child) sfd %d cfd %d", serversock,
+ clientsock);
+ service (clientsock);
+ //return 0;
+ }
+
+ /* Collect any exit statuses (lazy). */
+
+#if 0
+ while (1)
+ {
+ pid = waitpid (-1, &childstatus, WNOHANG);
+ if (pid < 0)
+ {
+ perror ("waitpid error?");
+ break;
+ }
+ else if (pid == 0)
+ {
+ break;
+ }
+ else if (WIFEXITED (childstatus))
+ {
+ log ("child %d exited with status %d", pid,
+ WEXITSTATUS (childstatus));
+ }
+ }
+#endif
+
+ }
+
+ /* Should never arrive here. */
+ return 254;
+}