|
1 |
| -use core::ffi::{c_int, c_uint, c_void, CStr}; |
| 1 | +use core::ffi::{c_char, c_int, c_uint, c_void, CStr}; |
2 | 2 | use core::{mem, ptr};
|
| 3 | +use std::ffi::CString; |
3 | 4 | use std::io::{ErrorKind, Read, Write};
|
4 | 5 | use std::sync::{Arc, Mutex};
|
5 | 6 |
|
@@ -360,6 +361,7 @@ struct Ssl {
|
360 | 361 | alpn_callback: callbacks::AlpnCallbackConfig,
|
361 | 362 | cert_callback: callbacks::CertCallbackConfig,
|
362 | 363 | sni_server_name: Option<ServerName<'static>>,
|
| 364 | + server_name: Option<CString>, |
363 | 365 | bio: Option<bio::Bio>,
|
364 | 366 | conn: ConnState,
|
365 | 367 | peer_cert: Option<x509::OwnedX509>,
|
@@ -390,6 +392,7 @@ impl Ssl {
|
390 | 392 | alpn_callback: inner.alpn_callback.clone(),
|
391 | 393 | cert_callback: inner.cert_callback.clone(),
|
392 | 394 | sni_server_name: None,
|
| 395 | + server_name: None, |
393 | 396 | bio: None,
|
394 | 397 | conn: ConnState::Nothing,
|
395 | 398 | peer_cert: None,
|
@@ -472,6 +475,33 @@ impl Ssl {
|
472 | 475 | }
|
473 | 476 | }
|
474 | 477 |
|
| 478 | + fn server_name_pointer(&mut self) -> *const c_char { |
| 479 | + // This does double duty (see `SSL_get_servername`): |
| 480 | + // |
| 481 | + // for clients, it is just `sni_server_name` |
| 482 | + // (filled in here, lazily) |
| 483 | + // |
| 484 | + // for servers, it is the client's offered SNI name |
| 485 | + // (filled in below in `prepare_accepted_callbacks`) |
| 486 | + // |
| 487 | + // the remaining annoyance is that the returned pointer has to NUL-terminated. |
| 488 | + |
| 489 | + match self.mode { |
| 490 | + ConnMode::Server => self.server_name.as_ref().map(|cstr| cstr.as_ptr()), |
| 491 | + ConnMode::Client | ConnMode::Unknown => match &self.server_name { |
| 492 | + Some(existing) => Some(existing.as_ptr()), |
| 493 | + None => { |
| 494 | + self.server_name = self |
| 495 | + .sni_server_name |
| 496 | + .as_ref() |
| 497 | + .and_then(|name| CString::new(name.to_str().as_bytes()).ok()); |
| 498 | + self.server_name.as_ref().map(|cstr| cstr.as_ptr()) |
| 499 | + } |
| 500 | + }, |
| 501 | + } |
| 502 | + .unwrap_or_else(ptr::null) |
| 503 | + } |
| 504 | + |
475 | 505 | fn set_bio(&mut self, bio: bio::Bio) {
|
476 | 506 | self.bio = Some(bio);
|
477 | 507 | }
|
@@ -573,6 +603,11 @@ impl Ssl {
|
573 | 603 | _ => unreachable!(),
|
574 | 604 | };
|
575 | 605 |
|
| 606 | + self.server_name = accepted |
| 607 | + .client_hello() |
| 608 | + .server_name() |
| 609 | + .and_then(|sni| CString::new(sni.as_bytes()).ok()); |
| 610 | + |
576 | 611 | if let Some(alpn_iter) = accepted.client_hello().alpn() {
|
577 | 612 | let offer = encode_alpn(alpn_iter);
|
578 | 613 | callbacks.add(Box::new(callbacks::AlpnPendingCallback {
|
|
0 commit comments