Permalink
Browse files

First public commit

  • Loading branch information...
0 parents commit 60084bb62961f295c619d26ae0315b22b4dcaae4 Jamie Turner committed Jun 10, 2011
Showing with 1,021 additions and 0 deletions.
  1. +25 −0 LICENSE
  2. +10 −0 Makefile
  3. +79 −0 README.md
  4. +109 −0 ringbuffer.c
  5. +67 −0 ringbuffer.h
  6. +731 −0 stud.c
25 LICENSE
@@ -0,0 +1,25 @@
+Copyright 2011 Bump Technologies, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY BUMP TECHNOLOGIES, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BUMP TECHNOLOGIES, INC. OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those of the
+authors and should not be interpreted as representing official policies, either expressed
+or implied, of Bump Technologies, Inc.
@@ -0,0 +1,10 @@
+all: stud
+
+stud: stud.c
+ gcc -O2 -g -std=c99 -fno-strict-aliasing -Wall -Werror -pedantic -I. -o stud ringbuffer.c stud.c -D_GNU_SOURCE -lssl -lcrypto -lev
+
+install: stud
+ cp stud /usr/local/bin
+
+clean:
+ rm -f stud *.o
@@ -0,0 +1,79 @@
+stud - The Scalable TLS Unwrapping Daemon
+=========================================
+
+`stud` is a network proxy that terminates TLS/SSL connections and forwards the
+unencrypted traffic to some backend. It's designed to handle 10s of thousands of
+connections efficiently on multicore machines.
+
+It follows a process-per-core model; a parent process spawns N children who
+each `accept()` on a common socket to distribute connected clients among them.
+Within each child, asynchronous socket I/O is conducted across the local
+connections using `libev` and `OpenSSL`'s nonblocking API. By default,
+`stud` has an overhead of ~200KB per connection--it preallocates
+some buffer space for data in flight between frontend in backend.
+
+`stud` has very few features--it's designed to be paired with an intelligent
+backend like haproxy or nginx. It maintains a strict 1:1 connection pattern
+with this backend handler so that the backend can dictate throttling behavior,
+maxmium connection behavior, availability of service, etc.
+
+`stud` has one "cool trick"--it will optionally write the client IPv4 address
+as the first four octets little endian. In this way, backends who care about
+the client IP can still access it even though `stud` itself appears to be
+the connected client.
+
+Requirements and Limitations
+----------------------------
+
+`stud` requires:
+
+ libev >= 4
+ openssl (recent, >=1.0.0 recommended)
+
+Stud does not yet support IPv6.
+
+Additionally, `stud` is currently Linux-only. While porting it to other POSIX
+platforms is likely trivial, it hasn't be done yet. Patches welcome!
+
+If you're handling a large number of connections, you'll
+probably want to raise `ulimit -n` before running `stud`.
+
+Installing
+----------
+
+To install `stud`:
+
+ $ make
+ $ sudo make install
+
+Usage
+-----
+
+The only required argument is a path to a PEM file that contains the certificate
+and private key.
+
+The entire set of arguments can be invoked with `stud -h`:
+
+ Encryption Methods:
+ --tls (TLSv1, default)
+ --ssl (SSLv2/SSLv3)
+
+ Socket:
+ -b HOST:PORT (backend [connect], default "127.0.0.1:8000")
+ -f HOST:PORT (frontend [bind], default "*:8443")
+
+ Performance:
+ -n CORES (number of worker processes, default 1)
+
+ Special:
+ --write-ipv4 (write remote IPv4 in first 4 octets
+ little-endian to backend)
+
+`stud` uses no configuration file.
+
+Authors
+-------
+
+`stud` was initially written by Jamie Turner <jamie@bu.mp> and is maintained
+by the Bump server team. It currently (6/11) provides server-side TLS
+termination for over 40 million Bump users.
@@ -0,0 +1,109 @@
+/**
+ * Copyright 2011 Bump Technologies, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BUMP TECHNOLOGIES, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BUMP TECHNOLOGIES, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of Bump Technologies, Inc.
+ *
+ **/
+
+#include "ringbuffer.h"
+#include <assert.h>
+
+/* Initialize a ringbuffer structure to empty */
+
+void ringbuffer_init(ringbuffer *rb) {
+ rb->head = &rb->slots[0];
+ rb->tail = &rb->slots[0];
+ rb->used = 0;
+ int x;
+ for (x=0; x<RING_SLOTS; x++)
+ rb->slots[x].next = &(rb->slots[(x + 1) % RING_SLOTS]);
+}
+
+/** READ FUNCTIONS **/
+
+/* Return a char * that represents the current unconsumed buffer */
+char * ringbuffer_read_next(ringbuffer *rb, int * length) {
+ assert(rb->used);
+ *length = rb->head->left;
+ return rb->head->ptr;
+}
+
+/* Mark consumption of only part of the read head buffer */
+void ringbuffer_read_skip(ringbuffer *rb, int length) {
+ assert(rb->used);
+ rb->head->ptr += length;
+ rb->head->left -= length;
+}
+
+/* Pop a consumed (fully read) head from the buffer */
+void ringbuffer_read_pop(ringbuffer *rb) {
+ assert(rb->used);
+ rb->head = rb->head->next;
+ rb->used--;
+}
+
+
+/** WRITE FUNCTIONS **/
+
+/* Return the tail ptr (current target of new writes) */
+char * ringbuffer_write_ptr(ringbuffer *rb) {
+ assert(rb->used < RING_SLOTS);
+ return rb->tail->data;
+}
+
+/* Mark the tail appended for `length` bytes, and move the cursor
+ * to the next slot */
+void ringbuffer_write_append(ringbuffer *rb, int length) {
+ assert(rb->used < RING_SLOTS);
+
+ rb->used++;
+
+ rb->tail->ptr = rb->tail->data;
+ rb->tail->left = length;
+ rb->tail = rb->tail->next;
+}
+
+/** RING STATE FUNCTIONS **/
+
+/* Used size of the ringbuffer */
+int ringbuffer_size(ringbuffer *rb) {
+ return rb->used;
+}
+
+/* Used size of the ringbuffer */
+int ringbuffer_capacity(ringbuffer *rb) {
+ return RING_SLOTS;
+}
+
+/* Is the ringbuffer completely empty (implies: no data to be written) */
+int ringbuffer_is_empty(ringbuffer *rb) {
+ return rb->used == 0;
+}
+
+/* Is the ringbuffer completely full (implies: no more data should be read) */
+int ringbuffer_is_full(ringbuffer *rb) {
+ return rb->used == RING_SLOTS;
+}
+
@@ -0,0 +1,67 @@
+/**
+ * Copyright 2011 Bump Technologies, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification, are
+ * permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this list of
+ * conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ * of conditions and the following disclaimer in the documentation and/or other materials
+ * provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BUMP TECHNOLOGIES, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BUMP TECHNOLOGIES, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those of the
+ * authors and should not be interpreted as representing official policies, either expressed
+ * or implied, of Bump Technologies, Inc.
+ *
+ **/
+
+#ifndef RINGBUFFER_H
+#define RINGBUFFER_H
+
+#include <stddef.h>
+
+/* Tweak these for potential memory/throughput tradeoffs */
+#define RING_SLOTS 3
+#define RING_DATA_LEN 1024 * 32
+
+typedef struct bufent {
+ char data[RING_DATA_LEN];
+ char *ptr;
+ size_t left;
+ struct bufent *next;
+} bufent;
+
+typedef struct ringbuffer {
+ bufent slots[RING_SLOTS];
+ bufent *head; // reads from the head
+ bufent *tail; // writes to the tail
+ size_t used;
+} ringbuffer;
+
+void ringbuffer_init(ringbuffer *rb);
+
+char * ringbuffer_read_next(ringbuffer *rb, int * length);
+void ringbuffer_read_skip(ringbuffer *rb, int length);
+void ringbuffer_read_pop(ringbuffer *rb);
+
+char * ringbuffer_write_ptr(ringbuffer *rb);
+void ringbuffer_write_append(ringbuffer *rb, int length);
+
+int ringbuffer_size(ringbuffer *rb);
+int ringbuffer_capacity(ringbuffer *rb);
+int ringbuffer_is_empty(ringbuffer *rb);
+int ringbuffer_is_full(ringbuffer *rb);
+
+#endif /* RINGBUFFER_H */
Oops, something went wrong.

0 comments on commit 60084bb

Please sign in to comment.