Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

DRAFT: Add NPN support to stud #10

Merged
merged 3 commits into from

2 participants

@georgekola
Owner

This adds NPN support to SPDY. Android SDK would use OK_HTTP and it requires NPN support.

@georgekola
Owner

@Fedor, I just based this off your commit 40b884a and chromiums project's NPN support
http://src.chromium.org/chrome/trunk/src/net/tools/flip_server/spdy_ssl.cc.
Can you please check if this is fine. I could not get the direct paste of your code to work and had to refer to chromium and openssl headers.

@ChrisFrancis Can you please confirm if OK HTTP works fine with this

@georgekola
Owner

@mranney what are your thoughts on this ?
I am just advertising spdy/3 support
We should probably not roll this into production for a month :)

We also need confirmation that android does not break with this.

@ChrisFrancis can you please confirm that our existing android app works fine with this.

stud.cc
@@ -1506,6 +1506,19 @@ static void ssl_write(struct ev_loop *loop, ev_io *w, int revents) {
}
}
+#ifdef OPENSSL_NPN_NEGOTIATED
+static const char ssl_npn_line[] =
+"\x06spdy/3" \
@indutny Collaborator
indutny added a note

Please add indent (2 or 4 spaces).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
stud.cc
@@ -1506,6 +1506,19 @@ static void ssl_write(struct ev_loop *loop, ev_io *w, int revents) {
}
}
+#ifdef OPENSSL_NPN_NEGOTIATED
+static const char ssl_npn_line[] =
+"\x06spdy/3" \
+"\x08http/1.1" \
+"\x08http/1.0";
+
+static int ssl_advertise_spdy(SSL* ssl, const unsigned char** data, unsigned int *len, void* arg) {
+ *data = (const unsigned char*) ssl_npn_line;
+ *len = strlen(ssl_npn_line);
@indutny Collaborator
indutny added a note

Could use sizeof() - 1 if you are giving away const char[].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@indutny
Collaborator

LGTM, but to merge it in master branch you'll need to introduce new configuration option.

@indutny
Collaborator

Almost finished working on NPN config option, will push to this branch

@indutny
Collaborator

@georgekola pushed, please review.

@georgekola
Owner

Looks Good!

@georgekola georgekola merged commit 26776f4 into master
@georgekola georgekola deleted the test/npn-support branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Feb 23, 2014
  1. @georgekola @indutny

    Add NPN support to stud

    georgekola authored indutny committed
  2. @indutny

    config: introduce NPN option

    indutny authored
  3. @indutny

    make: fix build on OSX

    indutny authored
This page is out of date. Refresh to see the latest.
Showing with 67 additions and 2 deletions.
  1. +1 −1  Makefile
  2. +42 −1 configuration.cc
  3. +3 −0  configuration.h
  4. +21 −0 stud.cc
View
2  Makefile
@@ -67,7 +67,7 @@ realall: $(ALL)
stud.o: stud.cc SimpleMemoryPool.hpp
-stud: $(OBJS) SimpleMemoryPool.hpp
+stud: $(OBJS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -o $@ $^ $(LDFLAGS)
deps/libev/.libs/libev.a: deps/libev/Makefile
View
43 configuration.cc
@@ -53,6 +53,7 @@
// BEGIN: configuration parameters
#define CFG_CIPHERS "ciphers"
#define CFG_SSL_ENGINE "ssl-engine"
+#define CFG_SSL_NPN "npn"
#define CFG_PREFER_SERVER_CIPHERS "prefer-server-ciphers"
#define CFG_EC_CURVE "ec-curve"
#define CFG_BACKEND "backend"
@@ -153,6 +154,9 @@ stud_config * config_new (void) {
r->CIPHER_SUITE = NULL;
r->ENGINE = NULL;
r->EC_CURVE = NULL;
+ r->NPN = NULL;
+ r->NPN_RAW = NULL;
+ r->NPN_RAW_LEN = 0;
r->BACKLOG = 100;
#ifdef USE_SHARED_CACHE
@@ -198,6 +202,8 @@ void config_destroy (stud_config *cfg) {
if (cfg->CIPHER_SUITE != NULL) free(cfg->CIPHER_SUITE);
if (cfg->ENGINE != NULL) free(cfg->ENGINE);
if (cfg->EC_CURVE != NULL) free(cfg->EC_CURVE);
+ if (cfg->NPN != NULL) free(cfg->NPN);
+ if (cfg->NPN_RAW != NULL) free(cfg->NPN_RAW);
#ifdef USE_SHARED_CACHE
if (cfg->SHCUPD_IP != NULL) free(cfg->SHCUPD_IP);
@@ -309,6 +315,29 @@ char * str_trim(char *str) {
return str;
}
+unsigned char * config_split_npn (char *src, int *out_len) {
+ if (src == NULL)
+ return NULL;
+
+ int len = strlen(src) + 1;
+ unsigned char *out = reinterpret_cast<unsigned char*>(malloc(len));
+ if (out == NULL)
+ return NULL;
+
+ /* Shift everything one byte right and replace commas with sizes */
+ memcpy(out + 1, src, len);
+ int off = 0;
+ for (int i = 1; i <= len; i++) {
+ if (i != len && out[i] != ',')
+ continue;
+ out[off] = i - off - 1;
+ off = i;
+ }
+
+ *out_len = len;
+ return out;
+}
+
char * config_assign_str (char **dst, char *v) {
if (*dst == NULL) {
if (v != NULL && strlen(v) > 0)
@@ -585,6 +614,12 @@ void config_param_validate (const char *k, char *v, stud_config *cfg, char *file
config_assign_str(&cfg->EC_CURVE, v);
}
}
+ else if (strcmp(k, CFG_SSL_NPN) == 0) {
+ if (v != NULL && strlen(v) > 0) {
+ config_assign_str(&cfg->NPN, v);
+ cfg->NPN_RAW = config_split_npn(cfg->NPN, &cfg->NPN_RAW_LEN);
+ }
+ }
else if (strcmp(k, CFG_PREFER_SERVER_CIPHERS) == 0) {
r = config_param_val_bool(v, &cfg->PREFER_SERVER_CIPHERS);
}
@@ -1027,6 +1062,12 @@ void config_print_default (FILE *fd, stud_config *cfg) {
fprintf(fd, FMT_QSTR, CFG_SSL_ENGINE, config_disp_str(cfg->ENGINE));
fprintf(fd, "\n");
+ fprintf(fd, "# Use specified SSL engine\n");
+ fprintf(fd, "#\n");
+ fprintf(fd, "# type: string\n");
+ fprintf(fd, FMT_QSTR, CFG_SSL_NPN, config_disp_str(cfg->NPN));
+ fprintf(fd, "\n");
+
fprintf(fd, "# Number of worker processes\n");
fprintf(fd, "#\n");
fprintf(fd, "# type: integer\n");
@@ -1241,7 +1282,7 @@ void config_parse_cli(int argc, char **argv, stud_config *cfg) {
break;
case 'e':
config_param_validate(CFG_SSL_ENGINE, optarg, cfg, NULL, 0);
- break;
+ break;
case 'O':
config_param_validate(CFG_PREFER_SERVER_CIPHERS, CFG_BOOL_ON, cfg, NULL, 0);
break;
View
3  configuration.h
@@ -55,6 +55,9 @@ struct __stud_config {
char *CIPHER_SUITE;
char *ENGINE;
char *EC_CURVE;
+ char *NPN;
+ unsigned char *NPN_RAW;
+ int NPN_RAW_LEN;
int BACKLOG;
#ifdef USE_SHARED_CACHE
int SHARED_CACHE;
View
21 stud.cc
@@ -1526,6 +1526,22 @@ static void ssl_write(struct ev_loop *loop, ev_io *w, int revents) {
}
}
+#ifdef OPENSSL_NPN_NEGOTIATED
+static int ssl_advertise_spdy(SSL* ssl,
+ const unsigned char** data,
+ unsigned int *len,
+ void* arg) {
+ if (CONFIG->NPN_RAW == NULL) {
+ *data = reinterpret_cast<const unsigned char*>("");
+ *len = 0;
+ } else {
+ *data = CONFIG->NPN_RAW;
+ *len = static_cast<unsigned int>(CONFIG->NPN_RAW_LEN);
+ }
+ return SSL_TLSEXT_ERR_OK;
+}
+#endif
+
/* libev read handler for the bound socket. Socket is accepted,
* the proxystate is allocated and initalized, and we're off the races
* connecting to the backend */
@@ -1592,6 +1608,11 @@ static void handle_accept(struct ev_loop *loop, ev_io *w, int revents) {
SSL_set_accept_state(ssl);
SSL_set_fd(ssl, client);
+#ifdef OPENSSL_NPN_NEGOTIATED
+ // Advertise SPDY support
+ SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_advertise_spdy, NULL);
+#endif
+
//proxystate *ps = (proxystate *)malloc(sizeof(proxystate));
proxystate *ps = SPool.Get();
if(unlikely(ps==NULL)){
Something went wrong with that request. Please try again.