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 ?
0 : ssl::create_ssl_client_context();
} 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 &&
!get_config()->spdy_downstream_no_tls ?
ssl::create_ssl_client_context() : 0;
@ -356,6 +357,8 @@ void fill_default_config()
mod_config()->spdy_upstream_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_version = 3;
@ -530,6 +533,16 @@ void print_help(std::ostream& out)
<< " frontend connection to 2**<N>.\n"
<< " Default: "
<< 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"
<< " Sets the initial window size of SPDY\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-spdy-no-tls", no_argument, &flag, 27},
{"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 }
};
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,
optarg));
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:
break;
}
@ -882,7 +907,7 @@ int main(int argc, char **argv)
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) {
print_usage(std::cerr);
LOG(FATAL) << "Too few arguments";

View File

@ -135,8 +135,13 @@ ClientHandler::ClientHandler(bufferevent *bev, int fd, SSL *ssl,
if(ssl_) {
set_bev_cb(0, upstream_writecb, upstream_eventcb);
} else {
// For client-mode
if(get_config()->client_mode) {
// Client mode
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);
}
}

View File

@ -75,6 +75,8 @@ const char
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_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_PROTO[] = "backend-spdy-proto";
const char SHRPX_OPT_PID_FILE[] = "pid-file";
@ -184,6 +186,23 @@ void set_config_str(char **destp, const char *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)
{
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";
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)) {
mod_config()->spdy_downstream_no_tls = util::strieq(optarg, "yes");
} else if(util::strieq(opt, SHRPX_OPT_BACKEND_SPDY_PROTO)) {
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;
int version = parse_spdy_proto(optarg);
if(version == -1) {
return -1;
}
} else {
mod_config()->spdy_downstream_version = version;
}
} else if(util::strieq(opt, SHRPX_OPT_PID_FILE)) {
set_config_str(&mod_config()->pid_file, optarg);
} 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_FRONTEND_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_PROTO[];
extern const char SHRPX_OPT_PID_FILE[];
@ -128,6 +130,8 @@ struct Config {
bool accesslog;
size_t spdy_upstream_window_bits;
size_t spdy_downstream_window_bits;
bool spdy_upstream_no_tls;
uint16_t spdy_upstream_version;
bool spdy_downstream_no_tls;
uint16_t spdy_downstream_version;
char *pid_file;