Skip to content

Commit

Permalink
Run an integration test covering TLS client APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
ctz committed Mar 26, 2024
1 parent 5eb6dd3 commit 8b62c8d
Show file tree
Hide file tree
Showing 7 changed files with 343 additions and 2 deletions.
5 changes: 4 additions & 1 deletion rustls-libssl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ifneq (,$(TARGET))
CARGOFLAGS += --target $(TARGET)
endif

all: target/ciphers target/constants target/$(PROFILE)/libssl.so.3
all: target/ciphers target/client target/constants target/$(PROFILE)/libssl.so.3

test: all
${CARGO} test --locked
Expand All @@ -42,6 +42,9 @@ target/%.o: tests/%.c | target
target/ciphers: target/ciphers.o
$(CC) -o $@ $^ $(LDFLAGS) $(shell pkg-config --libs openssl)

target/client: target/client.o
$(CC) -o $@ $^ $(LDFLAGS) $(shell pkg-config --libs openssl)

target/constants: target/constants.o
$(CC) -o $@ $^ $(LDFLAGS) $(shell pkg-config --libs openssl)

Expand Down
30 changes: 30 additions & 0 deletions rustls-libssl/test-ca/rsa/ca.cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-----BEGIN CERTIFICATE-----
MIIFFTCCAv2gAwIBAgIUZBEaAuV4ORnPH4GxeJGyEiqXUN8wDQYJKoZIhvcNAQEL
BQAwGjEYMBYGA1UEAwwPcG9ueXRvd24gUlNBIENBMB4XDTIzMTIyMTE3MjMxNFoX
DTMzMTIxODE3MjMxNFowGjEYMBYGA1UEAwwPcG9ueXRvd24gUlNBIENBMIICIjAN
BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAzvK/b5WhfthXBMVIHboJJuR9XuG9
+ioSrlzwT9DW7QV31UpgBUZyf1nvT7CmDplNiWZtpqSdJ9pjskBIj5dv4m5cX8A9
fK1IATdkd6j5/c2ZFkqi5k9iPeJa5rZY6SoGKgvBEr/Y5oiO8HZJZOFetafSr6zV
WRAsKlagrmiNS0oiWC0P0yPVWZyhlHHbtYrHtF/CuWEJ9HqzUk9KeTPwgjfphlYJ
YM0bCZzqN8TEbWPksU1WnmU15YbTgjwI0bNjUXA7W9LmMvbW7EXFJ2+LI+oiF3mk
TQEXqhfdTL9NtqAikD+cfAM1y5e5QSpi8dQuexBteFtXphRZzFk8M9DVKHyngKTH
/QZo6B4Gj9VPrNRPlbPkpbnu8JWD7hO/22VLU4YhghsdwQ/833pfokdV89NMoLo4
JOUzbTTGtjH0bq6LWTMtLifuQ4H0D1WLtdy/EGgKptnTaeYaXNYT7+v+NNcBHaW8
W3Orbx0s9IXgQnZTk1u03RbRdIxNxqm+HYEM8gT6S9IUymNZkzDCfZC0bC/saevd
zVE2xpZmuLOfhDl+EcalDYNPrM72+NzkAwRPFGec+bcUEhBxhvxpav+SxDiRC1gD
43qFU7hVfuqVH/EFp0lR3I3Xo8TZ5OIgEyJ5vQH5Ne1+C+sqdCqdGoqf1TZuIE80
ZwKYcMnRwDXpiGsCAwEAAaNTMFEwHQYDVR0OBBYEFEIQj1cHn3me0sRqu6KjbEb2
kb8rMB8GA1UdIwQYMBaAFEIQj1cHn3me0sRqu6KjbEb2kb8rMA8GA1UdEwEB/wQF
MAMBAf8wDQYJKoZIhvcNAQELBQADggIBAEKDnm8x+NOaWNrPNH5kIlGD0tGdDJvw
/KvBZmkMcgFkb4zhbbeUmlu0j5CX4+6Lck0uw62zRgP4Nw3x36W3DL7pmoV4MYHC
djNG1ruNoojvgZyyGgMaSabto0nSHSE9opAorrSXB9RoOv2WcBuQSBNl72eaCQ1F
4kAYjKN6ZwPxEdTsdEmqWyUyEPy6E5kNoM0jW1uI2ZBxzbIOYeePvQ3muUSIMtmC
jShiEOOpmYpzENsAMouY3ZN+CWVS5kB5umnYSviQlAVEKSjC764FD9vMLL+rNhfP
fz+y6EhKcnnYy7mdXIRY73uh5eMyCLUO0yr2Y2ophhD8D79f2w7KtYjaSKfAch0L
lETe9Ch+fGDxUCph3J1IuR/3n01ZjB47WXu/yDZ6s7SHGXIgPaptzP+nZkDnmlZX
bvjB5s6r4U2spuqeLxrwd/1Jin7It+LOYLVmkihpbta9+/KKiXOuSYN1rSiQ2XKp
n1ZN0XxhcZzsALklBIU+Lm11b8gPVS7rXqll/sDmaAH9Iw+AXwUYjCb62Gy58yzu
uk3Q+msRr3oVI9bBhmEXmZxyENYJrw305qOlI3+tHBoJLUSP6zQ214aEu4trJr5K
kmbF7DZRG9MSBXeRk7e5ojK13xI1/XCjgIOTkGxF4rEFbVwhc0B8zS/2x3zw0fkE
M4J0J+gz0QYr
-----END CERTIFICATE-----
24 changes: 24 additions & 0 deletions rustls-libssl/test-ca/rsa/end.cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIIEGDCCAoCgAwIBAgICAcgwDQYJKoZIhvcNAQELBQAwLDEqMCgGA1UEAwwhcG9u
eXRvd24gUlNBIGxldmVsIDIgaW50ZXJtZWRpYXRlMB4XDTIzMTIyMTE3MjMxNVoX
DTI5MDYxMjE3MjMxNVowGTEXMBUGA1UEAwwOdGVzdHNlcnZlci5jb20wggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDI1plwQmA+rr6Evlvn2hzIB/zYKlx
Tm14SPzomxpaf3OpzXzHuOn34yVvU1vTDijUl/YJbcnx052m0075SYeuW08VQB/p
zjhLrFp1ULSD272IddbB88T8Jq/VZ5dAxBB1q6Tm0vGBYQ8eIcmJv+fJQTbTXHKQ
KPHQRmVyqXVkwvwcgEJi9gpOcEEpJ6SDGdyGh1ck3wGnhrSpmsu+hwUVi7las+Ka
QUlvkmD+UGQKo8Ta91Xu8ja25QLTpjVcYxbi719rtA6I9DpX4+3aeIy/0s1xk0Xi
yMXIjSl3dn47gp3IZFRCECuoTdOwOZ9+y9ENnpHvZ84jCBXddU09qheJAgMBAAGj
gdYwgdMwDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFAUefby7
fPnK64BnGdIizLlWDkbPMEIGA1UdIwQ7MDmAFJCh13RFfpFyZ5LRR+A6ndRRvvGa
oR6kHDAaMRgwFgYDVQQDDA9wb255dG93biBSU0EgQ0GCAXswUwYDVR0RBEwwSoIO
dGVzdHNlcnZlci5jb22HBMYzZAGCFXNlY29uZC50ZXN0c2VydmVyLmNvbYcQIAEN
uAAAAAAAAAAAAAAAAYIJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBgQC2gxGT
c3aayDPR5/ICnuK8aVSsM67xRsGsWvzBxdyyXaB+qSGxa+sCkw8guuAp2W7MrrO/
zu7yhXDI2nyav6ZP6NvLABFYZ6pXokV/Hj4rQpCDVxvvDVh/E/rW/wx6z580zfdo
auHqUCD9QfR97nENwtGv7ESLN6qFeU0CsJd2GE3y3pnadlpCW3AYHeLX4crm7poj
SfG1F4ipqM1i0knQN86KBzG5PO49azGJGmcsu5lPFQgTRvvR7W+Niq/kIQPu00AW
so8aSB1gp2lypUGHqwsrd51yrQ374jKvXSDt1ptc0xDI9004TuYre9XQsyjxq4Qn
VjmpnKLCbumkrlELf93oomWxT5g6Nb/vu1TUgsrdWgDAW0AZ+rfcWorrZAjbvYw9
4MJ1PdAmeg+sk51xoh2KF7syHPaMcNCaoSBtXrB5LqrAxixdmB6ORM/KlQU7h9A7
X+WysEwMowV2MsGr8VsHxYTOpoiE8nUPfnRmbrGPpUU24bzvqTxtxxqQU14=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions rustls-libssl/test-ca/rsa/end.key
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDDI1plwQmA+rr6
Evlvn2hzIB/zYKlxTm14SPzomxpaf3OpzXzHuOn34yVvU1vTDijUl/YJbcnx052m
0075SYeuW08VQB/pzjhLrFp1ULSD272IddbB88T8Jq/VZ5dAxBB1q6Tm0vGBYQ8e
IcmJv+fJQTbTXHKQKPHQRmVyqXVkwvwcgEJi9gpOcEEpJ6SDGdyGh1ck3wGnhrSp
msu+hwUVi7las+KaQUlvkmD+UGQKo8Ta91Xu8ja25QLTpjVcYxbi719rtA6I9DpX
4+3aeIy/0s1xk0XiyMXIjSl3dn47gp3IZFRCECuoTdOwOZ9+y9ENnpHvZ84jCBXd
dU09qheJAgMBAAECggEABbzZYJqPc/prWwUJzo1qXdA5AEf8U3eR4nKK9S/yU2zh
8sE3BQxb3M0SAbb6wTbuXmnlcxuGT5UAUrJt5QiTc739kktjZNWKdDcqJb7sv9/L
L+L/II7RYPSmQOkd2mqpbTxRyfOz5DD9Z85ohaNd5l4Dha13NOPvUEdxnjB7Yi4I
YbUYZ/Zq6MUosFRObS0XPBvk6d+zDI3WUZatVTNfuS7fqI1BvkXs5EkV34DQXgQs
LKb1LFAoEZoh64UnfkONIT9oG4OTbbaQ9gCbfQPpKw07GuaMdtjp0QD0yldOKvL4
V4crSZyj2f3LnPCqCjUwcz6quKSUqUgosVApH+JCcQKBgQDpaGXy3laYTK3zbauh
+eHY5Ia+7fM2ETZx4LfwAYA1K5E84T98swpO571lZVrbOKjBukpUrbHdOcEVcBRH
BTvCh1vL1AXXWR0cCvWtp/WAbu90rDqgu6mxaD+V8wGq29URTWOCRG1WA7zeNHPB
0XAZPLQVeqeSvHGLSqyPf4aoHQKBgQDWBqvl5To7P4ZT6VFl18v0EB3zgzpRuyC3
xKKz5mGw4tuvspdMU2XaOGQsRl5emMijGeII7JUweHbBdkq44S2FZ9wyn4+I+8Oi
Atu4Nce06ARnw+5RRcJlSs/LrExfOtxF3xp8EQqpL/jEO03n7G5cwcFwuWTKoVTI
0RwcuU4JXQKBgDBMCvRzb2W6UDBT3DT7GPGhcARoBnCEpUhxIH6IQPg/mKEJVvK9
tX9YUod9row4MCtOGf1lp61IOxztgTSk75W0HpmRuNezt+NKnUWewJ0f12rEDKmf
y2BLWwTzMMAjFvaqldGpyRoIUfeE0QMlDFYcioL7S1uApNoWzJgw4jM9AoGBANIk
osuLku1xphbl08JHbD4rRP1AMBbnwWwuagJxhiID3OhaVivfBvaIv/Ko9Se0o+th
EorooGODJDc4So3Uqrl+DLq36Fr7uE5uuAXa6Ec8OHcZ7flmoUSLfBPjDOnEBVul
f3+py+nq7Drgb9H0VzhEFgb0QX6jgXfbudqKJ5ERAoGAR5Q6wQEoT9VT53nuKprl
3K/6agd+4wlpVQW0W1LImdrJHRHUXO7KJe7Bo5rtjL3lw8dCl3olHlLPJKg9frMn
ZWvJ2t0zca18S76rNcsPew2BecJxNRFlGwdcE1BBA2p/yzBhsZbIO7eqfh+dK5va
rnlrPNbWDhylxMaU4/CoU7k=
-----END PRIVATE KEY-----
28 changes: 28 additions & 0 deletions rustls-libssl/test-ca/rsa/inter.cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN CERTIFICATE-----
MIIEwDCCAqigAwIBAgIBezANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDDA9wb255
dG93biBSU0EgQ0EwHhcNMjMxMjIxMTcyMzE1WhcNMzMxMjE4MTcyMzE1WjAsMSow
KAYDVQQDDCFwb255dG93biBSU0EgbGV2ZWwgMiBpbnRlcm1lZGlhdGUwggGiMA0G
CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQDC9IRIszo5zkkxlz+pkU8otrZ2Jwlf
BQ4j5heoPkpmvFss2fDElZZCVhZt54ehk2+oRuZhfgldfmuT0KCQEMnx8iN7K+pk
2LgaAVGzT4X/NBv+qamgkzRu9UvrS5NrlWutHsPPRt2TldVVJ1UEiLuWrrFMQwi+
JATjgBHz6PhhD+UnPszZM/SJaBmtMXT99rO/sS6aaQhkZJCSDVVOnnecXafshkEF
tlMkKDRTTxxTOiTGu2NSH5MMzB3F952AiG8ZDONRSyBtxh/kpRV6+idO/4ufIQ3w
ZUPjLlRZIF9cDIGJXRU+cjYvMSV6yPzM2rP+67dPS9N7gQS1AFiMOlLQRbp3Sz9e
R6eetX/ggaHPcIzNv+pLp0L4+8PINZWhcJnZUlgkNR9Gg25mdPC6BLpWH20NH37V
VfSs40ytxHyw5QRokwwjcGUmlzXSJf0R+eUhXkJAmR+bgKbQKRbCW6M+byNdphfu
c3R2irNvRbYkwTOP3FvFkcC+cYyMIHyKihMCAwEAAaN/MH0wHQYDVR0OBBYEFJCh
13RFfpFyZ5LRR+A6ndRRvvGaMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMBBggrBgEF
BQcDAjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jAfBgNVHSMEGDAWgBRCEI9X
B595ntLEaruio2xG9pG/KzANBgkqhkiG9w0BAQsFAAOCAgEAxyqRDyGCkF07q/2P
44Mkwg+olQdT7moiO7V7MauwLZmCNqkr4hQcAk1NKi1QdYw/xCgd/x7PQ/INVMYN
oAG/xxr4nh0whygSsPGk9LkzoeG4dfeVv7tbsYw+4o7wU9kgCM1v0c2vMskyHh3F
vdMJV+5hWZqHZLUOZY1l9ziJysz/aSD4WpMtXdwT5fFgbJ8zggcMADkIESSBPrK5
ykjFqFnoryK938IUw8fHEdU5ZdjM+1li4Q6P3YT6ovY9aA9gXbD/xb4mUb5kG+ug
tmGV+MDvi6Qgyt1O9ZgaW0tLdbjdxzTjEgU0KwUDpK6AZ9ebcyL5PGj3JA15ZPvS
36AHH/3N+u3w1Poyxb8NxyOgNY7AX3hRQax9G1/43F3VZ1C991xVrwWL++mRD+Ai
5FhMKjZ258+8DKgYaT2JIExwNWA5taafmR2CKpxgVWSFLha/WogJH3kyyTJHXLjU
Bm5qvwqWAvS3Px+WkSbtqFKRDCs+oaj2wGGuwxqEEEriMJ26AC3Si2n9k0a17TOj
lezKgblBHlpokEgcqOkRDB8k1g/Hkx7eRX4RlBRJ4PVRFT6qSTyy3dESsWhb7Sz2
+uB8SQIYH+5QXwD3MpNrg2BILQYtcciPiGmLNyQB3ZvJUKcj0n63CjxAfcSnbkUF
AnF6iUVbZu9AMRaBDiRdNLGnBms=
-----END CERTIFICATE-----
141 changes: 141 additions & 0 deletions rustls-libssl/tests/client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/**
* Simple client test program.
*
* Expects to connect to an `openssl s_server -rev` server.
*/

#include <assert.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

#include <openssl/err.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>

static int trace(int rc, const char *str) {
printf("%s: %d\n", str, rc);
return rc;
}

#define TRACE(fn) trace((fn), #fn)

static void hexdump(const char *label, const void *buf, int n) {
const uint8_t *ubuf = (const uint8_t *)buf;
printf("%s (%d bytes): ", label, n);
for (int i = 0; i < n; i++) {
printf("%02x", ubuf[i]);
}
printf("\n");
}

static void dump_openssl_error_stack(void) {
if (ERR_peek_error() != 0) {
printf("openssl error: ");
ERR_print_errors_fp(stdout);
}
}

int main(int argc, char **argv) {
if (argc != 4) {
printf("%s <host> <port> <ca-cert>\n\n", argv[0]);
return 1;
}

const char *host = argv[1], *port = argv[2], *cacert = argv[3];

struct addrinfo *result = NULL;
TRACE(getaddrinfo(host, port, NULL, &result));

int sock = TRACE(
socket(result->ai_family, result->ai_socktype, result->ai_protocol));
TRACE(connect(sock, result->ai_addr, result->ai_addrlen));
freeaddrinfo(result);

TRACE(OPENSSL_init_ssl(0, NULL));
dump_openssl_error_stack();
SSL_CTX *ctx = SSL_CTX_new(TLS_method());
dump_openssl_error_stack();
if (strcmp(cacert, "insecure") != 0) {
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
dump_openssl_error_stack();
TRACE(SSL_CTX_load_verify_file(ctx, cacert));
dump_openssl_error_stack();
} else {
printf("certificate verification disabled\n");
}
TRACE(SSL_CTX_set_alpn_protos(ctx, (const uint8_t *)"\x02hi\x05world", 9));
dump_openssl_error_stack();
SSL *ssl = SSL_new(ctx);
dump_openssl_error_stack();
TRACE(SSL_set1_host(ssl, host));
dump_openssl_error_stack();
TRACE(SSL_set_fd(ssl, sock));
dump_openssl_error_stack();
TRACE(SSL_connect(ssl));
dump_openssl_error_stack();

// check the alpn (also sees that SSL_connect completed handshake)
const uint8_t *alpn_ptr = NULL;
unsigned int alpn_len = 0;
SSL_get0_alpn_selected(ssl, &alpn_ptr, &alpn_len);
hexdump("alpn", alpn_ptr, alpn_len);

printf("version: %s\n", SSL_get_version(ssl));
printf("verify-result: %ld\n", SSL_get_verify_result(ssl));
printf("cipher: %s\n", SSL_CIPHER_standard_name(SSL_get_current_cipher(ssl)));

// check the peer certificate and chain
X509 *cert = SSL_get1_peer_certificate(ssl);
if (cert) {
char *name = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
printf("server subject: %s\n", name);
free(name);
} else {
printf("server cert absent\n");
}
X509_free(cert);

STACK_OF(X509) *chain = SSL_get_peer_cert_chain(ssl);
if (chain) {
printf("%d certs in server chain\n", sk_X509_num(chain));
for (int i = 0; i < sk_X509_num(chain); i++) {
X509 *cert = sk_X509_value(chain, i);
char *name = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
printf(" %d: %s\n", i, name);
free(name);
}
} else {
printf("server cert chain absent\n");
}

// write some data and close
int wr = TRACE(SSL_write(ssl, "hello", 5));
dump_openssl_error_stack();
assert(wr == 5);
TRACE(SSL_shutdown(ssl));
dump_openssl_error_stack();

// read back data, using SSL_pending on the way
char buf[10] = {0};
int rd = TRACE(SSL_read(ssl, buf, 1));
dump_openssl_error_stack();
TRACE(SSL_pending(ssl));
dump_openssl_error_stack();
TRACE(SSL_has_pending(ssl));
dump_openssl_error_stack();
int rd2 = TRACE(SSL_read(ssl, buf + 1, sizeof(buf) - 1));
hexdump("result", buf, rd + rd2);
assert(memcmp(buf, "olleh\n", 6) == 0);

close(sock);
SSL_free(ssl);
SSL_CTX_free(ctx);

printf("PASS\n\n");
return 0;
}
89 changes: 88 additions & 1 deletion rustls-libssl/tests/runner.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::process::{Command, Output, Stdio};
use std::process::{Child, Command, Output, Stdio};
use std::{net, thread, time};

/* Note:
*
Expand All @@ -11,6 +12,67 @@ use std::process::{Command, Output, Stdio};
* to actually use OpenSSL's libssl.
*/

#[test]
#[ignore]
fn client() {
let _server = KillOnDrop(
Command::new("openssl")
.args(&[
"s_server",
"-cert",
"test-ca/rsa/end.cert",
"-cert_chain",
"test-ca/rsa/inter.cert",
"-key",
"test-ca/rsa/end.key",
"-alpn",
"hello,world",
"-accept",
"localhost:4443",
"-rev",
])
.env("LD_LIBRARY_PATH", "")
.spawn()
.expect("failed to start openssl s_server"),
);

wait_for_port(4443);

let openssl_insecure_output = Command::new("target/client")
.env("LD_LIBRARY_PATH", "")
.args(&["localhost", "4443", "insecure"])
.stdout(Stdio::piped())
.output()
.map(print_output)
.unwrap();

let rustls_insecure_output = Command::new("target/client")
.args(&["localhost", "4443", "insecure"])
.stdout(Stdio::piped())
.output()
.map(print_output)
.unwrap();

assert_eq!(openssl_insecure_output, rustls_insecure_output);

let openssl_secure_output = Command::new("target/client")
.env("LD_LIBRARY_PATH", "")
.args(&["localhost", "4443", "test-ca/rsa/ca.cert"])
.stdout(Stdio::piped())
.output()
.map(print_output)
.unwrap();

let rustls_secure_output = Command::new("target/client")
.args(&["localhost", "4443", "test-ca/rsa/ca.cert"])
.stdout(Stdio::piped())
.output()
.map(print_output)
.unwrap();

assert_eq!(openssl_secure_output, rustls_secure_output);
}

#[test]
#[ignore]
fn constants() {
Expand Down Expand Up @@ -49,6 +111,15 @@ fn ciphers() {
assert_eq!(openssl_output, rustls_output);
}

struct KillOnDrop(Child);

impl Drop for KillOnDrop {
fn drop(&mut self) {
self.0.kill().expect("failed to kill subprocess");
self.0.wait().expect("failed to wait for killed subprocess");
}
}

fn print_output(out: Output) -> Output {
println!("status: {:?}\n", out.status);
println!(
Expand All @@ -61,3 +132,19 @@ fn print_output(out: Output) -> Output {
);
out
}

/// Wait until we can connect to localhost:port.
fn wait_for_port(port: u16) -> Option<()> {
let mut count = 0;
loop {
thread::sleep(time::Duration::from_millis(500));
if net::TcpStream::connect(("localhost", port)).is_ok() {
return Some(());
}
println!("waiting for port {port}");
count += 1;
if count == 10 {
return None;
}
}
}

0 comments on commit 8b62c8d

Please sign in to comment.