18 #if defined(HANDSHAKER_SUPPORTED)
22 #include <sys/socket.h>
24 #include <sys/types.h>
57 return test_state->quic_transport->ReadHandshake();
73 if (timeout_ret < 0) {
74 fprintf(
stderr,
"Error retransmitting.\n");
118 if (
ret != ret2 || ssl_err != ssl_err2 ||
err != err2) {
119 fprintf(
stderr,
"Repeating %s did not replay the error.\n",
name);
122 fprintf(
stderr,
"Wanted: %d %d %s\n",
ret, ssl_err,
buf);
124 fprintf(
stderr,
"Got: %d %d %s\n", ret2, ssl_err2,
buf);
133 #if defined(HANDSHAKER_SUPPORTED)
149 static bool HandoffReady(
SSL *ssl,
int ret) {
157 }
while (
ret < 0 && errno == EINTR);
161 static ssize_t write_eintr(
int fd,
const void *
in,
size_t len) {
165 }
while (
ret < 0 && errno == EINTR);
169 static ssize_t waitpid_eintr(pid_t pid,
int *wstatus,
int options) {
173 }
while (
ret < 0 && errno == EINTR);
180 static bool Proxy(
BIO *
socket,
bool async,
int control,
int rfd,
int wfd) {
185 FD_SET(control, &rfds);
186 int fd_max = wfd > control ? wfd : control;
187 if (select(fd_max + 1, &rfds,
nullptr,
nullptr,
nullptr) == -1) {
194 if (FD_ISSET(wfd, &rfds) &&
200 fprintf(
stderr,
"BIO_write wrote nothing\n");
208 fprintf(
stderr,
"BIO_write failed\n");
219 if (!FD_ISSET(control, &rfds)) {
224 if (read_eintr(control, &
msg, 1) != 1) {
229 case kControlMsgDone:
231 case kControlMsgError:
233 case kControlMsgWantRead:
236 fprintf(
stderr,
"Unknown control message from handshaker: %c\n",
msg);
248 fprintf(
stderr,
"BIO_read failed\n");
276 fprintf(
stderr,
"bad header\n");
280 while (remaining > 0) {
282 size_t len = remaining >
sizeof(readbuf) ?
sizeof(readbuf) : remaining;
283 if (!proxy_data(readbuf,
len)) {
291 msg = kControlMsgWriteCompleted;
292 if (write_eintr(control, &
msg, 1) != 1) {
302 explicit ScopedFD(
int fd) : fd_(fd) {}
312 int fd()
const {
return fd_; }
314 void Reset(
int fd = -1) {
325 class ScopedProcess {
327 ScopedProcess() : pid_(-1) {}
328 ~ScopedProcess() {
Reset(); }
330 ScopedProcess(ScopedProcess &&other) { *
this =
std::move(other); }
331 ScopedProcess &operator=(ScopedProcess &&other) {
337 pid_t pid()
const {
return pid_; }
339 void Reset(pid_t pid = -1) {
348 bool Wait(
int *out_status) {
352 if (waitpid_eintr(pid_, out_status, 0) != pid_) {
363 class FileActionsDestroyer {
365 explicit FileActionsDestroyer(posix_spawn_file_actions_t *actions)
366 : actions_(actions) {}
367 ~FileActionsDestroyer() { posix_spawn_file_actions_destroy(actions_); }
368 FileActionsDestroyer(
const FileActionsDestroyer &) =
delete;
369 FileActionsDestroyer &operator=(
const FileActionsDestroyer &) =
delete;
372 posix_spawn_file_actions_t *actions_;
381 static bool StartHandshaker(ScopedProcess *
out,
ScopedFD *out_control,
383 std::map<int, int> map_fds,
384 std::vector<int> close_fds) {
385 if (
config->handshaker_path.empty()) {
386 fprintf(
stderr,
"no -handshaker-path specified\n");
391 perror(
config->handshaker_path.c_str());
395 std::vector<const char *>
args;
396 args.push_back(
config->handshaker_path.c_str());
397 static const char kResumeFlag[] =
"-handshaker-resume";
399 args.push_back(kResumeFlag);
402 for (
int j = 0;
j <
config->argc; ++
j) {
405 args.push_back(
nullptr);
409 if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, control) != 0) {
410 perror(
"socketpair");
413 ScopedFD scoped_control0(control[0]), scoped_control1(control[1]);
414 close_fds.push_back(control[0]);
415 map_fds[kFdControl] = control[1];
417 posix_spawn_file_actions_t actions;
418 if (posix_spawn_file_actions_init(&actions) != 0) {
421 FileActionsDestroyer actions_destroyer(&actions);
422 for (
int fd : close_fds) {
423 if (posix_spawn_file_actions_addclose(&actions, fd) != 0) {
427 if (!map_fds.empty()) {
428 int max_fd = STDERR_FILENO;
429 for (
const auto &
pair : map_fds) {
437 std::map<int, int> temp_fds;
438 int next_fd = max_fd + 1;
439 for (
const auto &
pair : map_fds) {
440 if (temp_fds.count(
pair.second)) {
443 temp_fds[
pair.second] = next_fd;
444 if (posix_spawn_file_actions_adddup2(&actions,
pair.second, next_fd) !=
446 posix_spawn_file_actions_addclose(&actions,
pair.second) != 0) {
451 for (
const auto &
pair : map_fds) {
452 if (posix_spawn_file_actions_adddup2(&actions, temp_fds[
pair.second],
458 for (
int fd = max_fd + 1; fd < next_fd; fd++) {
459 if (posix_spawn_file_actions_addclose(&actions, fd) != 0) {
471 if (posix_spawn(&pid,
args[0], &actions,
nullptr,
472 const_cast<char *
const *
>(
args.data()),
environ) != 0) {
477 *out_control =
std::move(scoped_control0);
485 std::vector<uint8_t> *
out) {
497 if (pipe(rfd) != 0) {
501 ScopedFD rfd0_closer(rfd[0]), rfd1_closer(rfd[1]);
503 if (pipe(wfd) != 0) {
507 ScopedFD wfd0_closer(wfd[0]), wfd1_closer(wfd[1]);
509 ScopedProcess handshaker;
511 if (!StartHandshaker(
512 &handshaker, &control,
config, is_resume,
513 {{kFdProxyToHandshaker, rfd[0]}, {kFdHandshakerToProxy, wfd[1]}},
521 if (write_eintr(control.fd(),
input.data(),
input.size()) == -1) {
525 bool ok = Proxy(bio,
config->async, control.fd(), rfd[1], wfd[0]);
527 if (!handshaker.Wait(&wstatus)) {
532 fprintf(
stderr,
"handshaker exited irregularly\n");
539 constexpr
size_t kBufSize = 1024 * 1024;
540 std::vector<uint8_t>
buf(kBufSize);
553 std::vector<uint8_t> *out_hints) {
554 ScopedProcess handshaker;
556 if (!StartHandshaker(&handshaker, &control,
config, is_resume, {}, {})) {
560 if (write_eintr(control.fd(),
input.data(),
input.size()) == -1) {
566 if (read_eintr(control.fd(), &
msg, 1) != 1) {
572 case kControlMsgDone: {
573 constexpr
size_t kBufSize = 1024 * 1024;
574 out_hints->resize(kBufSize);
576 read_eintr(control.fd(), out_hints->data(), out_hints->size());
581 out_hints->resize(
len);
582 *out_has_hints =
true;
585 case kControlMsgError:
586 *out_has_hints =
false;
589 fprintf(
stderr,
"Unknown control message from handshaker: %c\n",
msg);
594 if (!handshaker.Wait(&wstatus)) {
599 fprintf(
stderr,
"handshaker exited irregularly\n");
610 std::vector<uint8_t> *out_handoff) {
617 "SSL_do_handshake", ssl,
619 }
while (!HandoffReady(ssl,
ret) &&
622 if (!HandoffReady(ssl,
ret)) {
623 fprintf(
stderr,
"Handshake failed while waiting for handoff.\n");
631 !
writer->WriteHandoff({CBB_data(cbb.get()), CBB_len(cbb.get())}) ||
634 fprintf(
stderr,
"Handoff serialisation failed.\n");
637 out_handoff->assign(
CBB_data(cbb.get()),
650 std::vector<uint8_t> handshaker_input;
654 std::vector<uint8_t>
out;
655 if (!PrepareHandoff(ssl->get(),
writer, &handshaker_input) ||
657 handshaker_input, &
out)) {
658 fprintf(
stderr,
"Handoff failed.\n");
663 UniquePtr<SSL> ssl_handback =
config->NewSSL(
ctx,
nullptr,
nullptr);
674 fprintf(
stderr,
"Handback failed.\n");
677 MoveBIOs(ssl_handback.get(), ssl->get());
701 std::vector<uint8_t> hints;
702 if (!RequestHandshakeHint(
705 &has_hints, &hints)) {
709 (!
writer->WriteHints(hints) ||
717 #endif // defined(HANDSHAKER_SUPPORTED)