ossl-guide-quic-client-block.7ossl 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. .\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.42)
  2. .\"
  3. .\" Standard preamble:
  4. .\" ========================================================================
  5. .de Sp \" Vertical space (when we can't use .PP)
  6. .if t .sp .5v
  7. .if n .sp
  8. ..
  9. .de Vb \" Begin verbatim text
  10. .ft CW
  11. .nf
  12. .ne \\$1
  13. ..
  14. .de Ve \" End verbatim text
  15. .ft R
  16. .fi
  17. ..
  18. .\" Set up some character translations and predefined strings. \*(-- will
  19. .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
  20. .\" double quote, and \*(R" will give a right double quote. \*(C+ will
  21. .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
  22. .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
  23. .\" nothing in troff, for use with C<>.
  24. .tr \(*W-
  25. .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
  26. .ie n \{\
  27. . ds -- \(*W-
  28. . ds PI pi
  29. . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
  30. . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
  31. . ds L" ""
  32. . ds R" ""
  33. . ds C` ""
  34. . ds C' ""
  35. 'br\}
  36. .el\{\
  37. . ds -- \|\(em\|
  38. . ds PI \(*p
  39. . ds L" ``
  40. . ds R" ''
  41. . ds C`
  42. . ds C'
  43. 'br\}
  44. .\"
  45. .\" Escape single quotes in literal strings from groff's Unicode transform.
  46. .ie \n(.g .ds Aq \(aq
  47. .el .ds Aq '
  48. .\"
  49. .\" If the F register is >0, we'll generate index entries on stderr for
  50. .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
  51. .\" entries marked with X<> in POD. Of course, you'll have to process the
  52. .\" output yourself in some meaningful fashion.
  53. .\"
  54. .\" Avoid warning from groff about undefined register 'F'.
  55. .de IX
  56. ..
  57. .nr rF 0
  58. .if \n(.g .if rF .nr rF 1
  59. .if (\n(rF:(\n(.g==0)) \{\
  60. . if \nF \{\
  61. . de IX
  62. . tm Index:\\$1\t\\n%\t"\\$2"
  63. ..
  64. . if !\nF==2 \{\
  65. . nr % 0
  66. . nr F 2
  67. . \}
  68. . \}
  69. .\}
  70. .rr rF
  71. .\"
  72. .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
  73. .\" Fear. Run. Save yourself. No user-serviceable parts.
  74. . \" fudge factors for nroff and troff
  75. .if n \{\
  76. . ds #H 0
  77. . ds #V .8m
  78. . ds #F .3m
  79. . ds #[ \f1
  80. . ds #] \fP
  81. .\}
  82. .if t \{\
  83. . ds #H ((1u-(\\\\n(.fu%2u))*.13m)
  84. . ds #V .6m
  85. . ds #F 0
  86. . ds #[ \&
  87. . ds #] \&
  88. .\}
  89. . \" simple accents for nroff and troff
  90. .if n \{\
  91. . ds ' \&
  92. . ds ` \&
  93. . ds ^ \&
  94. . ds , \&
  95. . ds ~ ~
  96. . ds /
  97. .\}
  98. .if t \{\
  99. . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
  100. . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
  101. . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
  102. . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
  103. . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
  104. . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
  105. .\}
  106. . \" troff and (daisy-wheel) nroff accents
  107. .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
  108. .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
  109. .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
  110. .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
  111. .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
  112. .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
  113. .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
  114. .ds ae a\h'-(\w'a'u*4/10)'e
  115. .ds Ae A\h'-(\w'A'u*4/10)'E
  116. . \" corrections for vroff
  117. .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
  118. .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
  119. . \" for low resolution devices (crt and lpr)
  120. .if \n(.H>23 .if \n(.V>19 \
  121. \{\
  122. . ds : e
  123. . ds 8 ss
  124. . ds o a
  125. . ds d- d\h'-1'\(ga
  126. . ds D- D\h'-1'\(hy
  127. . ds th \o'bp'
  128. . ds Th \o'LP'
  129. . ds ae ae
  130. . ds Ae AE
  131. .\}
  132. .rm #[ #] #H #V #F C
  133. .\" ========================================================================
  134. .\"
  135. .IX Title "OSSL-GUIDE-QUIC-CLIENT-BLOCK 7ossl"
  136. .TH OSSL-GUIDE-QUIC-CLIENT-BLOCK 7ossl "2024-09-03" "3.3.2" "OpenSSL"
  137. .\" For nroff, turn off justification. Always turn off hyphenation; it makes
  138. .\" way too many mistakes in technical documents.
  139. .if n .ad l
  140. .nh
  141. .SH "NAME"
  142. ossl\-guide\-quic\-client\-block
  143. \&\- OpenSSL Guide: Writing a simple blocking QUIC client
  144. .SH "SIMPLE BLOCKING QUIC CLIENT EXAMPLE"
  145. .IX Header "SIMPLE BLOCKING QUIC CLIENT EXAMPLE"
  146. This page will present various source code samples demonstrating how to write
  147. a simple blocking \s-1QUIC\s0 client application which connects to a server, sends an
  148. \&\s-1HTTP/1.0\s0 request to it, and reads back the response. Note that \s-1HTTP/1.0\s0 over
  149. \&\s-1QUIC\s0 is non-standard and will not be supported by real world servers. This is
  150. for demonstration purposes only.
  151. .PP
  152. We assume that you already have OpenSSL installed on your system; that you
  153. already have some fundamental understanding of OpenSSL concepts, \s-1TLS\s0 and \s-1QUIC\s0
  154. (see \fBossl\-guide\-libraries\-introduction\fR\|(7), \fBossl\-guide\-tls\-introduction\fR\|(7)
  155. and \fBossl\-guide\-quic\-introduction\fR\|(7)); and that you know how to
  156. write and build C code and link it against the libcrypto and libssl libraries
  157. that are provided by OpenSSL. It also assumes that you have a basic
  158. understanding of \s-1UDP/IP\s0 and sockets. The example code that we build in this
  159. tutorial will amend the blocking \s-1TLS\s0 client example that is covered in
  160. \&\fBossl\-guide\-tls\-client\-block\fR\|(7). Only the differences between that client and
  161. this one will be discussed so we also assume that you have run through and
  162. understand that tutorial.
  163. .PP
  164. For this tutorial our client will be using a single \s-1QUIC\s0 stream. A subsequent
  165. tutorial will discuss how to write a multi-stream client (see
  166. \&\fBossl\-guide\-quic\-multi\-stream\fR\|(7)).
  167. .PP
  168. The complete source code for this example blocking \s-1QUIC\s0 client is available in
  169. the \f(CW\*(C`demos/guide\*(C'\fR directory of the OpenSSL source distribution in the file
  170. \&\f(CW\*(C`quic\-client\-block.c\*(C'\fR. It is also available online at
  171. <https://github.com/openssl/openssl/blob/master/demos/guide/quic\-client\-block.c>.
  172. .SS "Creating the \s-1SSL_CTX\s0 and \s-1SSL\s0 objects"
  173. .IX Subsection "Creating the SSL_CTX and SSL objects"
  174. In the \s-1TLS\s0 tutorial (\fBossl\-guide\-tls\-client\-block\fR\|(7)) we created an \fB\s-1SSL_CTX\s0\fR
  175. object for our client and used it to create an \fB\s-1SSL\s0\fR object to represent the
  176. \&\s-1TLS\s0 connection. A \s-1QUIC\s0 connection works in exactly the same way. We first create
  177. an \fB\s-1SSL_CTX\s0\fR object and then use it to create an \fB\s-1SSL\s0\fR object to represent the
  178. \&\s-1QUIC\s0 connection.
  179. .PP
  180. As in the \s-1TLS\s0 example the first step is to create an \fB\s-1SSL_CTX\s0\fR object for our
  181. client. This is done in the same way as before except that we use a different
  182. \&\*(L"method\*(R". OpenSSL offers two different \s-1QUIC\s0 client methods, i.e.
  183. \&\fBOSSL_QUIC_client_method\fR\|(3) and \fBOSSL_QUIC_client_thread_method\fR\|(3).
  184. .PP
  185. The first one is the equivalent of \fBTLS_client_method\fR\|(3) but for the \s-1QUIC\s0
  186. protocol. The second one is the same, but it will additionally create a
  187. background thread for handling time based events (known as \*(L"thread assisted
  188. mode\*(R", see \fBossl\-guide\-quic\-introduction\fR\|(7)). For this tutorial we will be
  189. using \fBOSSL_QUIC_client_method\fR\|(3) because we will not be leaving the \s-1QUIC\s0
  190. connection idle in our application and so thread assisted mode is not needed.
  191. .PP
  192. .Vb 10
  193. \& /*
  194. \& * Create an SSL_CTX which we can use to create SSL objects from. We
  195. \& * want an SSL_CTX for creating clients so we use OSSL_QUIC_client_method()
  196. \& * here.
  197. \& */
  198. \& ctx = SSL_CTX_new(OSSL_QUIC_client_method());
  199. \& if (ctx == NULL) {
  200. \& printf("Failed to create the SSL_CTX\en");
  201. \& goto end;
  202. \& }
  203. .Ve
  204. .PP
  205. The other setup steps that we applied to the \fB\s-1SSL_CTX\s0\fR for \s-1TLS\s0 also apply to
  206. \&\s-1QUIC\s0 except for restricting the \s-1TLS\s0 versions that we are willing to accept. The
  207. \&\s-1QUIC\s0 protocol implementation in OpenSSL currently only supports TLSv1.3. There
  208. is no need to call \fBSSL_CTX_set_min_proto_version\fR\|(3) or
  209. \&\fBSSL_CTX_set_max_proto_version\fR\|(3) in an OpenSSL \s-1QUIC\s0 application, and any such
  210. call will be ignored.
  211. .PP
  212. Once the \fB\s-1SSL_CTX\s0\fR is created, the \fB\s-1SSL\s0\fR object is constructed in exactly the
  213. same way as for the \s-1TLS\s0 application.
  214. .SS "Creating the socket and \s-1BIO\s0"
  215. .IX Subsection "Creating the socket and BIO"
  216. A major difference between \s-1TLS\s0 and \s-1QUIC\s0 is the underlying transport protocol.
  217. \&\s-1TLS\s0 uses \s-1TCP\s0 while \s-1QUIC\s0 uses \s-1UDP.\s0 The way that the \s-1QUIC\s0 socket is created in our
  218. example code is much the same as for \s-1TLS.\s0 We use the \fBBIO_lookup_ex\fR\|(3) and
  219. \&\fBBIO_socket\fR\|(3) helper functions as we did in the previous tutorial except that
  220. we pass \fB\s-1SOCK_DGRAM\s0\fR as an argument to indicate \s-1UDP\s0 (instead of \fB\s-1SOCK_STREAM\s0\fR
  221. for \s-1TCP\s0).
  222. .PP
  223. .Vb 6
  224. \& /*
  225. \& * Lookup IP address info for the server.
  226. \& */
  227. \& if (!BIO_lookup_ex(hostname, port, BIO_LOOKUP_CLIENT, family, SOCK_DGRAM, 0,
  228. \& &res))
  229. \& return NULL;
  230. \&
  231. \& /*
  232. \& * Loop through all the possible addresses for the server and find one
  233. \& * we can connect to.
  234. \& */
  235. \& for (ai = res; ai != NULL; ai = BIO_ADDRINFO_next(ai)) {
  236. \& /*
  237. \& * Create a TCP socket. We could equally use non\-OpenSSL calls such
  238. \& * as "socket" here for this and the subsequent connect and close
  239. \& * functions. But for portability reasons and also so that we get
  240. \& * errors on the OpenSSL stack in the event of a failure we use
  241. \& * OpenSSL\*(Aqs versions of these functions.
  242. \& */
  243. \& sock = BIO_socket(BIO_ADDRINFO_family(ai), SOCK_DGRAM, 0, 0);
  244. \& if (sock == \-1)
  245. \& continue;
  246. \&
  247. \& /* Connect the socket to the server\*(Aqs address */
  248. \& if (!BIO_connect(sock, BIO_ADDRINFO_address(ai), 0)) {
  249. \& BIO_closesocket(sock);
  250. \& sock = \-1;
  251. \& continue;
  252. \& }
  253. \&
  254. \& /* Set to nonblocking mode */
  255. \& if (!BIO_socket_nbio(sock, 1)) {
  256. \& BIO_closesocket(sock);
  257. \& sock = \-1;
  258. \& continue;
  259. \& }
  260. \&
  261. \& break;
  262. \& }
  263. \&
  264. \& if (sock != \-1) {
  265. \& *peer_addr = BIO_ADDR_dup(BIO_ADDRINFO_address(ai));
  266. \& if (*peer_addr == NULL) {
  267. \& BIO_closesocket(sock);
  268. \& return NULL;
  269. \& }
  270. \& }
  271. \&
  272. \& /* Free the address information resources we allocated earlier */
  273. \& BIO_ADDRINFO_free(res);
  274. .Ve
  275. .PP
  276. You may notice a couple of other differences between this code and the version
  277. that we used for \s-1TLS.\s0
  278. .PP
  279. Firstly, we set the socket into nonblocking mode. This must always be done for
  280. an OpenSSL \s-1QUIC\s0 application. This may be surprising considering that we are
  281. trying to write a blocking client. Despite this the \fB\s-1SSL\s0\fR object will still
  282. have blocking behaviour. See \fBossl\-guide\-quic\-introduction\fR\|(7) for further
  283. information on this.
  284. .PP
  285. Secondly, we take note of the \s-1IP\s0 address of the peer that we are connecting to.
  286. We store that information away. We will need it later.
  287. .PP
  288. See \fBBIO_lookup_ex\fR\|(3), \fBBIO_socket\fR\|(3), \fBBIO_connect\fR\|(3),
  289. \&\fBBIO_closesocket\fR\|(3), \fBBIO_ADDRINFO_next\fR\|(3), \fBBIO_ADDRINFO_address\fR\|(3),
  290. \&\fBBIO_ADDRINFO_free\fR\|(3) and \fBBIO_ADDR_dup\fR\|(3) for further information on the
  291. functions used here. In the above example code the \fBhostname\fR and \fBport\fR
  292. variables are strings, e.g. \*(L"www.example.com\*(R" and \*(L"443\*(R".
  293. .PP
  294. As for our \s-1TLS\s0 client, once the socket has been created and connected we need to
  295. associate it with a \s-1BIO\s0 object:
  296. .PP
  297. .Vb 1
  298. \& BIO *bio;
  299. \&
  300. \& /* Create a BIO to wrap the socket */
  301. \& bio = BIO_new(BIO_s_datagram());
  302. \& if (bio == NULL) {
  303. \& BIO_closesocket(sock);
  304. \& return NULL;
  305. \& }
  306. \&
  307. \& /*
  308. \& * Associate the newly created BIO with the underlying socket. By
  309. \& * passing BIO_CLOSE here the socket will be automatically closed when
  310. \& * the BIO is freed. Alternatively you can use BIO_NOCLOSE, in which
  311. \& * case you must close the socket explicitly when it is no longer
  312. \& * needed.
  313. \& */
  314. \& BIO_set_fd(bio, sock, BIO_CLOSE);
  315. .Ve
  316. .PP
  317. Note the use of \fBBIO_s_datagram\fR\|(3) here as opposed to \fBBIO_s_socket\fR\|(3) that
  318. we used for our \s-1TLS\s0 client. This is again due to the fact that \s-1QUIC\s0 uses \s-1UDP\s0
  319. instead of \s-1TCP\s0 for its transport layer. See \fBBIO_new\fR\|(3), \fBBIO_s_datagram\fR\|(3)
  320. and \fBBIO_set_fd\fR\|(3) for further information on these functions.
  321. .SS "Setting the server's hostname"
  322. .IX Subsection "Setting the server's hostname"
  323. As in the \s-1TLS\s0 tutorial we need to set the server's hostname both for \s-1SNI\s0 (Server
  324. Name Indication) and for certificate validation purposes. The steps for this are
  325. identical to the \s-1TLS\s0 tutorial and won't be repeated here.
  326. .SS "Setting the \s-1ALPN\s0"
  327. .IX Subsection "Setting the ALPN"
  328. \&\s-1ALPN\s0 (Application-Layer Protocol Negotiation) is a feature of \s-1TLS\s0 that enables
  329. the application to negotiate which protocol will be used over the connection.
  330. For example, if you intend to use \s-1HTTP/3\s0 over the connection then the \s-1ALPN\s0 value
  331. for that is \*(L"h3\*(R" (see
  332. <https://www.iana.org/assignments/tls\-extensiontype\-values/tls\-extensiontype\-values.xml#alpn\-protocol\-ids>).
  333. OpenSSL provides the ability for a client to specify the \s-1ALPN\s0 to use via the
  334. \&\fBSSL_set_alpn_protos\fR\|(3) function. This is optional for a \s-1TLS\s0 client and so our
  335. simple client that we developed in \fBossl\-guide\-tls\-client\-block\fR\|(7) did not use
  336. it. However \s-1QUIC\s0 mandates that the \s-1TLS\s0 handshake used in establishing a \s-1QUIC\s0
  337. connection must use \s-1ALPN.\s0
  338. .PP
  339. .Vb 1
  340. \& unsigned char alpn[] = { 8, \*(Aqh\*(Aq, \*(Aqt\*(Aq, \*(Aqt\*(Aq, \*(Aqp\*(Aq, \*(Aq/\*(Aq, \*(Aq1\*(Aq, \*(Aq.\*(Aq, \*(Aq0\*(Aq };
  341. \&
  342. \& /* SSL_set_alpn_protos returns 0 for success! */
  343. \& if (SSL_set_alpn_protos(ssl, alpn, sizeof(alpn)) != 0) {
  344. \& printf("Failed to set the ALPN for the connection\en");
  345. \& goto end;
  346. \& }
  347. .Ve
  348. .PP
  349. The \s-1ALPN\s0 is specified using a length prefixed array of unsigned chars (it is not
  350. a \s-1NUL\s0 terminated string). Our original \s-1TLS\s0 blocking client demo was using
  351. \&\s-1HTTP/1.0.\s0 We will use the same for this example. Unlike most OpenSSL functions
  352. \&\fBSSL_set_alpn_protos\fR\|(3) returns zero for success and nonzero for failure.
  353. .SS "Setting the peer address"
  354. .IX Subsection "Setting the peer address"
  355. An OpenSSL \s-1QUIC\s0 application must specify the target address of the server that
  356. is being connected to. In \*(L"Creating the socket and \s-1BIO\*(R"\s0 above we saved that
  357. address away for future use. Now we need to use it via the
  358. \&\fBSSL_set1_initial_peer_addr\fR\|(3) function.
  359. .PP
  360. .Vb 5
  361. \& /* Set the IP address of the remote peer */
  362. \& if (!SSL_set1_initial_peer_addr(ssl, peer_addr)) {
  363. \& printf("Failed to set the initial peer address\en");
  364. \& goto end;
  365. \& }
  366. .Ve
  367. .PP
  368. Note that we will need to free the \fBpeer_addr\fR value that we allocated via
  369. \&\fBBIO_ADDR_dup\fR\|(3) earlier:
  370. .PP
  371. .Vb 1
  372. \& BIO_ADDR_free(peer_addr);
  373. .Ve
  374. .SS "The handshake and application data transfer"
  375. .IX Subsection "The handshake and application data transfer"
  376. Once initial setup of the \fB\s-1SSL\s0\fR object is complete then we perform the
  377. handshake via \fBSSL_connect\fR\|(3) in exactly the same way as we did for the \s-1TLS\s0
  378. client, so we won't repeat it here.
  379. .PP
  380. We can also perform data transfer using a default \s-1QUIC\s0 stream that is
  381. automatically associated with the \fB\s-1SSL\s0\fR object for us. We can transmit data
  382. using \fBSSL_write_ex\fR\|(3), and receive data using \fBSSL_read_ex\fR\|(3) in the same
  383. way as for \s-1TLS.\s0 The main difference is that we have to account for failures
  384. slightly differently. With \s-1QUIC\s0 the stream can be reset by the peer (which is
  385. fatal for that stream), but the underlying connection itself may still be
  386. healthy.
  387. .PP
  388. .Vb 10
  389. \& /*
  390. \& * Get up to sizeof(buf) bytes of the response. We keep reading until the
  391. \& * server closes the connection.
  392. \& */
  393. \& while (SSL_read_ex(ssl, buf, sizeof(buf), &readbytes)) {
  394. \& /*
  395. \& * OpenSSL does not guarantee that the returned data is a string or
  396. \& * that it is NUL terminated so we use fwrite() to write the exact
  397. \& * number of bytes that we read. The data could be non\-printable or
  398. \& * have NUL characters in the middle of it. For this simple example
  399. \& * we\*(Aqre going to print it to stdout anyway.
  400. \& */
  401. \& fwrite(buf, 1, readbytes, stdout);
  402. \& }
  403. \& /* In case the response didn\*(Aqt finish with a newline we add one now */
  404. \& printf("\en");
  405. \&
  406. \& /*
  407. \& * Check whether we finished the while loop above normally or as the
  408. \& * result of an error. The 0 argument to SSL_get_error() is the return
  409. \& * code we received from the SSL_read_ex() call. It must be 0 in order
  410. \& * to get here. Normal completion is indicated by SSL_ERROR_ZERO_RETURN. In
  411. \& * QUIC terms this means that the peer has sent FIN on the stream to
  412. \& * indicate that no further data will be sent.
  413. \& */
  414. \& switch (SSL_get_error(ssl, 0)) {
  415. \& case SSL_ERROR_ZERO_RETURN:
  416. \& /* Normal completion of the stream */
  417. \& break;
  418. \&
  419. \& case SSL_ERROR_SSL:
  420. \& /*
  421. \& * Some stream fatal error occurred. This could be because of a stream
  422. \& * reset \- or some failure occurred on the underlying connection.
  423. \& */
  424. \& switch (SSL_get_stream_read_state(ssl)) {
  425. \& case SSL_STREAM_STATE_RESET_REMOTE:
  426. \& printf("Stream reset occurred\en");
  427. \& /* The stream has been reset but the connection is still healthy. */
  428. \& break;
  429. \&
  430. \& case SSL_STREAM_STATE_CONN_CLOSED:
  431. \& printf("Connection closed\en");
  432. \& /* Connection is already closed. Skip SSL_shutdown() */
  433. \& goto end;
  434. \&
  435. \& default:
  436. \& printf("Unknown stream failure\en");
  437. \& break;
  438. \& }
  439. \& break;
  440. \&
  441. \& default:
  442. \& /* Some other unexpected error occurred */
  443. \& printf ("Failed reading remaining data\en");
  444. \& break;
  445. \& }
  446. .Ve
  447. .PP
  448. In the above code example you can see that \fB\s-1SSL_ERROR_SSL\s0\fR indicates a stream
  449. fatal error. We can use \fBSSL_get_stream_read_state\fR\|(3) to determine whether the
  450. stream has been reset, or if some other fatal error has occurred.
  451. .SS "Shutting down the connection"
  452. .IX Subsection "Shutting down the connection"
  453. In the \s-1TLS\s0 tutorial we knew that the server had finished sending data because
  454. \&\fBSSL_read_ex\fR\|(3) returned 0, and \fBSSL_get_error\fR\|(3) returned
  455. \&\fB\s-1SSL_ERROR_ZERO_RETURN\s0\fR. The same is true with \s-1QUIC\s0 except that
  456. \&\fB\s-1SSL_ERROR_ZERO_RETURN\s0\fR should be interpreted slightly differently. With \s-1TLS\s0
  457. we knew that this meant that the server had sent a \*(L"close_notify\*(R" alert. No
  458. more data will be sent from the server on that connection.
  459. .PP
  460. With \s-1QUIC\s0 it means that the server has indicated \*(L"\s-1FIN\*(R"\s0 on the stream, meaning
  461. that it will no longer send any more data on that stream. However this only
  462. gives us information about the stream itself and does not tell us anything about
  463. the underlying connection. More data could still be sent from the server on some
  464. other stream. Additionally, although the server will not send any more data to
  465. the client, it does not prevent the client from sending more data to the server.
  466. .PP
  467. In this tutorial, once we have finished reading data from the server on the one
  468. stream that we are using, we will close the connection down. As before we do
  469. this via the \fBSSL_shutdown\fR\|(3) function. This example for \s-1QUIC\s0 is very similar
  470. to the \s-1TLS\s0 version. However the \fBSSL_shutdown\fR\|(3) function will need to be
  471. called more than once:
  472. .PP
  473. .Vb 11
  474. \& /*
  475. \& * Repeatedly call SSL_shutdown() until the connection is fully
  476. \& * closed.
  477. \& */
  478. \& do {
  479. \& ret = SSL_shutdown(ssl);
  480. \& if (ret < 0) {
  481. \& printf("Error shutting down: %d\en", ret);
  482. \& goto end;
  483. \& }
  484. \& } while (ret != 1);
  485. .Ve
  486. .PP
  487. The shutdown process is in two stages. In the first stage we wait until all the
  488. data we have buffered for sending on any stream has been successfully sent and
  489. acknowledged by the peer, and then we send a \s-1CONNECTION_CLOSE\s0 to the peer to
  490. indicate that the connection is no longer usable. This immediately closes the
  491. connection and no more data can be sent or received. \fBSSL_shutdown\fR\|(3) returns
  492. 0 once the first stage has been completed.
  493. .PP
  494. In the second stage the connection enters a \*(L"closing\*(R" state. Application data
  495. cannot be sent or received in this state, but late arriving packets coming from
  496. the peer will be handled appropriately. Once this stage has completed
  497. successfully \fBSSL_shutdown\fR\|(3) will return 1 to indicate success.
  498. .SH "FURTHER READING"
  499. .IX Header "FURTHER READING"
  500. See \fBossl\-guide\-quic\-multi\-stream\fR\|(7) to read a tutorial on how to modify the
  501. client developed on this page to support multiple streams.
  502. .SH "SEE ALSO"
  503. .IX Header "SEE ALSO"
  504. \&\fBossl\-guide\-introduction\fR\|(7), \fBossl\-guide\-libraries\-introduction\fR\|(7),
  505. \&\fBossl\-guide\-libssl\-introduction\fR\|(7), \fBossl\-guide\-tls\-introduction\fR\|(7),
  506. \&\fBossl\-guide\-tls\-client\-block\fR\|(7), \fBossl\-guide\-quic\-introduction\fR\|(7)
  507. .SH "COPYRIGHT"
  508. .IX Header "COPYRIGHT"
  509. Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
  510. .PP
  511. Licensed under the Apache License 2.0 (the \*(L"License\*(R"). You may not use
  512. this file except in compliance with the License. You can obtain a copy
  513. in the file \s-1LICENSE\s0 in the source distribution or at
  514. <https://www.openssl.org/source/license.html>.