shrpx: Support non-TLS SPDY in frontend connection

This commit is contained in:
Tatsuhiro Tsujikawa 2013-03-24 21:03:39 +09:00
parent 439b34f49f
commit 7d709fa3ff
4 changed files with 70 additions and 11 deletions

View File

@ -243,7 +243,8 @@ int event_loop()
cl_ssl_ctx = get_config()->spdy_downstream_no_tls ? cl_ssl_ctx = get_config()->spdy_downstream_no_tls ?
0 : ssl::create_ssl_client_context(); 0 : ssl::create_ssl_client_context();
} else { } else {
sv_ssl_ctx = get_config()->default_ssl_ctx; sv_ssl_ctx = get_config()->spdy_upstream_no_tls ?
0 : get_config()->default_ssl_ctx;
cl_ssl_ctx = get_config()->spdy_bridge && cl_ssl_ctx = get_config()->spdy_bridge &&
!get_config()->spdy_downstream_no_tls ? !get_config()->spdy_downstream_no_tls ?
ssl::create_ssl_client_context() : 0; ssl::create_ssl_client_context() : 0;
@ -356,6 +357,8 @@ void fill_default_config()
mod_config()->spdy_upstream_window_bits = 16; mod_config()->spdy_upstream_window_bits = 16;
mod_config()->spdy_downstream_window_bits = 16; mod_config()->spdy_downstream_window_bits = 16;
mod_config()->spdy_upstream_no_tls = false;
mod_config()->spdy_upstream_version = 3;
mod_config()->spdy_downstream_no_tls = false; mod_config()->spdy_downstream_no_tls = false;
mod_config()->spdy_downstream_version = 3; mod_config()->spdy_downstream_version = 3;
@ -530,6 +533,16 @@ void print_help(std::ostream& out)
<< " frontend connection to 2**<N>.\n" << " frontend connection to 2**<N>.\n"
<< " Default: " << " Default: "
<< get_config()->spdy_upstream_window_bits << "\n" << get_config()->spdy_upstream_window_bits << "\n"
<< " --frontend-spdy-no-tls\n"
<< " Disable SSL/TLS on frontend SPDY\n"
<< " connections. SPDY protocol must be specified\n"
<< " using --frontend-spdy-proto. This option\n"
<< " also disables frontend HTTP/1.1.\n"
<< " --frontend-spdy-proto\n"
<< " Specify SPDY protocol used in frontend\n"
<< " connection if --frontend-spdy-no-tls is\n"
<< " used. Default: spdy/"
<< get_config()->spdy_upstream_version << "\n"
<< " --backend-spdy-window-bits=<N>\n" << " --backend-spdy-window-bits=<N>\n"
<< " Sets the initial window size of SPDY\n" << " Sets the initial window size of SPDY\n"
<< " backend connection to 2**<N>.\n" << " backend connection to 2**<N>.\n"
@ -644,6 +657,8 @@ int main(int argc, char **argv)
{"backend-http-proxy-uri", required_argument, &flag, 26}, {"backend-http-proxy-uri", required_argument, &flag, 26},
{"backend-spdy-no-tls", no_argument, &flag, 27}, {"backend-spdy-no-tls", no_argument, &flag, 27},
{"backend-spdy-proto", required_argument, &flag, 28}, {"backend-spdy-proto", required_argument, &flag, 28},
{"frontend-spdy-no-tls", no_argument, &flag, 29},
{"frontend-spdy-proto", required_argument, &flag, 30},
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
int option_index = 0; int option_index = 0;
@ -813,6 +828,16 @@ int main(int argc, char **argv)
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_BACKEND_SPDY_PROTO, cmdcfgs.push_back(std::make_pair(SHRPX_OPT_BACKEND_SPDY_PROTO,
optarg)); optarg));
break; break;
case 29:
// --frontend-spdy-no-tls
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_FRONTEND_SPDY_NO_TLS,
"yes"));
break;
case 30:
// --frontend-spdy-proto
cmdcfgs.push_back(std::make_pair(SHRPX_OPT_FRONTEND_SPDY_PROTO,
optarg));
break;
default: default:
break; break;
} }
@ -882,7 +907,7 @@ int main(int argc, char **argv)
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
if(!get_config()->client_mode) { if(!get_config()->client_mode && !get_config()->spdy_upstream_no_tls) {
if(!get_config()->private_key_file || !get_config()->cert_file) { if(!get_config()->private_key_file || !get_config()->cert_file) {
print_usage(std::cerr); print_usage(std::cerr);
LOG(FATAL) << "Too few arguments"; LOG(FATAL) << "Too few arguments";

View File

@ -135,8 +135,13 @@ ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl,
if(ssl_) { if(ssl_) {
set_bev_cb(0, upstream_writecb, upstream_eventcb); set_bev_cb(0, upstream_writecb, upstream_eventcb);
} else { } else {
// For client-mode if(get_config()->client_mode) {
// Client mode
upstream_ = new HttpsUpstream(this); upstream_ = new HttpsUpstream(this);
} else {
// no-TLS SPDY
upstream_ = new SpdyUpstream(get_config()->spdy_upstream_version, this);
}
set_bev_cb(upstream_readcb, upstream_writecb, upstream_eventcb); set_bev_cb(upstream_readcb, upstream_writecb, upstream_eventcb);
} }
} }

View File

@ -75,6 +75,8 @@ const char
SHRPX_OPT_BACKEND_KEEP_ALIVE_TIMEOUT[] = "backend-keep-alive-timeout"; SHRPX_OPT_BACKEND_KEEP_ALIVE_TIMEOUT[] = "backend-keep-alive-timeout";
const char SHRPX_OPT_FRONTEND_SPDY_WINDOW_BITS[] = "frontend-spdy-window-bits"; const char SHRPX_OPT_FRONTEND_SPDY_WINDOW_BITS[] = "frontend-spdy-window-bits";
const char SHRPX_OPT_BACKEND_SPDY_WINDOW_BITS[] = "backend-spdy-window-bits"; const char SHRPX_OPT_BACKEND_SPDY_WINDOW_BITS[] = "backend-spdy-window-bits";
const char SHRPX_OPT_FRONTEND_SPDY_NO_TLS[] = "frontend-spdy-no-tls";
const char SHRPX_OPT_FRONTEND_SPDY_PROTO[] = "frontend-spdy-proto";
const char SHRPX_OPT_BACKEND_SPDY_NO_TLS[] = "backend-spdy-no-tls"; const char SHRPX_OPT_BACKEND_SPDY_NO_TLS[] = "backend-spdy-no-tls";
const char SHRPX_OPT_BACKEND_SPDY_PROTO[] = "backend-spdy-proto"; const char SHRPX_OPT_BACKEND_SPDY_PROTO[] = "backend-spdy-proto";
const char SHRPX_OPT_PID_FILE[] = "pid-file"; const char SHRPX_OPT_PID_FILE[] = "pid-file";
@ -184,6 +186,23 @@ void set_config_str(char **destp, const char *val)
*destp = strdup(val); *destp = strdup(val);
} }
namespace {
// Parses |optarg| as SPDY NPN protocol string and returns SPDY
// protocol version number. This function returns -1 on error.
int parse_spdy_proto(const char *optarg)
{
size_t len = strlen(optarg);
const unsigned char *proto;
proto = reinterpret_cast<const unsigned char*>(optarg);
uint16_t version = spdylay_npn_get_version(proto, len);
if(!version) {
LOG(ERROR) << "Unsupported SPDY version: " << optarg;
return -1;
}
return version;
}
} // namespace
int parse_config(const char *opt, const char *optarg) int parse_config(const char *opt, const char *optarg)
{ {
char host[NI_MAXHOST]; char host[NI_MAXHOST];
@ -263,18 +282,24 @@ int parse_config(const char *opt, const char *optarg)
<< " specify the integer in the range [0, 30], inclusive"; << " specify the integer in the range [0, 30], inclusive";
return -1; return -1;
} }
} else if(util::strieq(opt, SHRPX_OPT_FRONTEND_SPDY_NO_TLS)) {
mod_config()->spdy_upstream_no_tls = util::strieq(optarg, "yes");
} else if(util::strieq(opt, SHRPX_OPT_FRONTEND_SPDY_PROTO)) {
int version = parse_spdy_proto(optarg);
if(version == -1) {
return -1;
} else {
mod_config()->spdy_upstream_version = version;
}
} else if(util::strieq(opt, SHRPX_OPT_BACKEND_SPDY_NO_TLS)) { } else if(util::strieq(opt, SHRPX_OPT_BACKEND_SPDY_NO_TLS)) {
mod_config()->spdy_downstream_no_tls = util::strieq(optarg, "yes"); mod_config()->spdy_downstream_no_tls = util::strieq(optarg, "yes");
} else if(util::strieq(opt, SHRPX_OPT_BACKEND_SPDY_PROTO)) { } else if(util::strieq(opt, SHRPX_OPT_BACKEND_SPDY_PROTO)) {
size_t len = strlen(optarg); int version = parse_spdy_proto(optarg);
const unsigned char *proto; if(version == -1) {
proto = reinterpret_cast<const unsigned char*>(optarg);
uint16_t version = spdylay_npn_get_version(proto, len);
if(!version) {
LOG(ERROR) << "Unsupported SPDY version: " << optarg;
return -1; return -1;
} } else {
mod_config()->spdy_downstream_version = version; mod_config()->spdy_downstream_version = version;
}
} else if(util::strieq(opt, SHRPX_OPT_PID_FILE)) { } else if(util::strieq(opt, SHRPX_OPT_PID_FILE)) {
set_config_str(&mod_config()->pid_file, optarg); set_config_str(&mod_config()->pid_file, optarg);
} else if(util::strieq(opt, SHRPX_OPT_USER)) { } else if(util::strieq(opt, SHRPX_OPT_USER)) {

View File

@ -68,6 +68,8 @@ extern const char SHRPX_OPT_ACCESSLOG[];
extern const char SHRPX_OPT_BACKEND_KEEP_ALIVE_TIMEOUT[]; extern const char SHRPX_OPT_BACKEND_KEEP_ALIVE_TIMEOUT[];
extern const char SHRPX_OPT_FRONTEND_SPDY_WINDOW_BITS[]; extern const char SHRPX_OPT_FRONTEND_SPDY_WINDOW_BITS[];
extern const char SHRPX_OPT_BACKEND_SPDY_WINDOW_BITS[]; extern const char SHRPX_OPT_BACKEND_SPDY_WINDOW_BITS[];
extern const char SHRPX_OPT_FRONTEND_SPDY_NO_TLS[];
extern const char SHRPX_OPT_FRONTEND_SPDY_PROTO[];
extern const char SHRPX_OPT_BACKEND_SPDY_NO_TLS[]; extern const char SHRPX_OPT_BACKEND_SPDY_NO_TLS[];
extern const char SHRPX_OPT_BACKEND_SPDY_PROTO[]; extern const char SHRPX_OPT_BACKEND_SPDY_PROTO[];
extern const char SHRPX_OPT_PID_FILE[]; extern const char SHRPX_OPT_PID_FILE[];
@ -128,6 +130,8 @@ struct Config {
bool accesslog; bool accesslog;
size_t spdy_upstream_window_bits; size_t spdy_upstream_window_bits;
size_t spdy_downstream_window_bits; size_t spdy_downstream_window_bits;
bool spdy_upstream_no_tls;
uint16_t spdy_upstream_version;
bool spdy_downstream_no_tls; bool spdy_downstream_no_tls;
uint16_t spdy_downstream_version; uint16_t spdy_downstream_version;
char *pid_file; char *pid_file;