-
Notifications
You must be signed in to change notification settings - Fork 818
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add allow-plain server ports attribute #9574
Changes from all commits
ac2e2df
cca5a99
467112f
3de3260
1be584a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,7 @@ using namespace std::literals; | |
#define SSL_WRITE_WOULD_BLOCK 10 | ||
#define SSL_WAIT_FOR_HOOK 11 | ||
#define SSL_WAIT_FOR_ASYNC 12 | ||
#define SSL_RESTART 13 | ||
|
||
ClassAllocator<SSLNetVConnection> sslNetVCAllocator("sslNetVCAllocator"); | ||
|
||
|
@@ -608,6 +609,12 @@ SSLNetVConnection::net_read_io(NetHandler *nh, EThread *lthread) | |
} else { | ||
ret = sslStartHandShake(SSL_EVENT_SERVER, err); | ||
} | ||
if (ret == SSL_RESTART) { | ||
// VC migrated into a new object | ||
// Just give up and go home. Events should trigger on the new vc | ||
Dbg(dbg_ctl_ssl, "Restart for allow plain"); | ||
return; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we need to decrement the recursion counter here? If no, it's difficult to understand. Want a comment why we don't need it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tried the recursion counts then changed the return value. I think that just sending back a different return value will suffice. I'll back out the recursion could and verify that everything still works. And update the PR There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And you are exactly right. Should be dropping the recursion count here too. Should use the scoped pattern to deal with the decrement if we really need to manipulate the recursion counter. |
||
} | ||
// If we have flipped to blind tunnel, don't read ahead | ||
if (this->handShakeReader) { | ||
if (this->attributes == HttpProxyPort::TRANSPORT_BLIND_TUNNEL) { | ||
|
@@ -1360,13 +1367,24 @@ SSLNetVConnection::sslServerHandShakeEvent(int &err) | |
err = errno; | ||
SSLVCDebug(this, "SSL handshake error: %s (%d), errno=%d", SSLErrorName(ssl_error), ssl_error, err); | ||
|
||
// start a blind tunnel if tr-pass is set and data does not look like ClientHello | ||
char *buf = handShakeBuffer ? handShakeBuffer->buf() : nullptr; | ||
if (getTransparentPassThrough() && buf && *buf != SSL_OP_HANDSHAKE) { | ||
SSLVCDebug(this, "Data does not look like SSL handshake, starting blind tunnel"); | ||
this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL; | ||
sslHandshakeStatus = SSLHandshakeStatus::SSL_HANDSHAKE_ONGOING; | ||
return EVENT_CONT; | ||
if (buf && *buf != SSL_OP_HANDSHAKE) { | ||
SSLVCDebug(this, "SSL hanshake error with bad HS buffer"); | ||
if (getAllowPlain()) { | ||
SSLVCDebug(this, "Try plain"); | ||
// If this doesn't look like a ClientHello, convert this connection to a UnixNetVC and send the | ||
// packet for Http Processing | ||
this->_migrateFromSSL(); | ||
return SSL_RESTART; | ||
} else if (getTransparentPassThrough()) { | ||
// start a blind tunnel if tr-pass is set and data does not look like ClientHello | ||
SSLVCDebug(this, "Data does not look like SSL handshake, starting blind tunnel"); | ||
this->attributes = HttpProxyPort::TRANSPORT_BLIND_TUNNEL; | ||
sslHandshakeStatus = SSLHandshakeStatus::SSL_HANDSHAKE_ONGOING; | ||
return EVENT_CONT; | ||
} else { | ||
SSLVCDebug(this, "Give up"); | ||
} | ||
} | ||
} | ||
|
||
|
@@ -2141,6 +2159,76 @@ SSLNetVConnection::_getNetProcessor() | |
return &sslNetProcessor; | ||
} | ||
|
||
void | ||
SSLNetVConnection::_propagateHandShakeBuffer(UnixNetVConnection *target, EThread *t) | ||
{ | ||
Debug("ssl", "allow-plain, handshake buffer ready to read=%" PRId64, this->handShakeHolder->read_avail()); | ||
// Take ownership of the handShake buffer | ||
this->sslHandshakeStatus = SSLHandshakeStatus::SSL_HANDSHAKE_DONE; | ||
NetState *s = &target->read; | ||
s->vio.buffer.writer_for(this->handShakeBuffer); | ||
s->vio.set_reader(this->handShakeHolder); | ||
this->handShakeHolder = nullptr; | ||
this->handShakeBuffer = nullptr; | ||
s->vio.vc_server = target; | ||
s->vio.cont = this->read.vio.cont; | ||
s->vio.mutex = this->read.vio.cont->mutex; | ||
// Passing along the buffer, don't keep a reading holding early in the buffer | ||
this->handShakeReader->dealloc(); | ||
this->handShakeReader = nullptr; | ||
|
||
// Kick things again, so the data that was copied into the | ||
// vio.read buffer gets processed | ||
target->readSignalDone(VC_EVENT_READ_COMPLETE, get_NetHandler(t)); | ||
} | ||
|
||
/* | ||
* Replaces the current SSLNetVConnection with a UnixNetVConnection | ||
* Propagates any data in the SSL handShakeBuffer to be processed | ||
* by the UnixNetVConnection logic | ||
*/ | ||
UnixNetVConnection * | ||
SSLNetVConnection::_migrateFromSSL() | ||
{ | ||
EThread *t = this_ethread(); | ||
NetHandler *client_nh = get_NetHandler(t); | ||
ink_assert(client_nh); | ||
|
||
Connection hold_con; | ||
hold_con.move(this->con); | ||
|
||
// We will leave the SSL object with the original SSLNetVC to be | ||
// cleaned up. Only moving the socket and handShakeBuffer | ||
// So no need to call _prepareMigration | ||
|
||
// Do_io_close will signal the VC to be freed on the original thread | ||
// Since we moved the con context, the fd will not be closed | ||
// Go ahead and remove the fd from the original thread's epoll structure, so it is not | ||
// processed on two threads simultaneously | ||
this->ep.stop(); | ||
|
||
// Create new VC: | ||
UnixNetVConnection *newvc = static_cast<UnixNetVConnection *>(unix_netProcessor.allocate_vc(t)); | ||
ink_assert(newvc != nullptr); | ||
if (newvc != nullptr && newvc->populate(hold_con, this->read.vio.cont, nullptr) != EVENT_DONE) { | ||
newvc->do_io_close(); | ||
Debug("ssl", "Failed to populate unixvc for allow-plain"); | ||
newvc = nullptr; | ||
} | ||
if (newvc != nullptr) { | ||
newvc->attributes = HttpProxyPort::TRANSPORT_DEFAULT; | ||
newvc->set_is_transparent(this->is_transparent); | ||
newvc->set_context(get_context()); | ||
newvc->options = this->options; | ||
Debug("ssl", "Move to unixvc for allow-plain"); | ||
this->_propagateHandShakeBuffer(newvc, t); | ||
} | ||
|
||
// Do not mark this closed until the end so it does not get freed by the other thread too soon | ||
this->do_io_close(); | ||
return newvc; | ||
} | ||
|
||
ssl_curve_id | ||
SSLNetVConnection::_get_tls_curve() const | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to look at aliased boolean or enum values for clarity.