tls_bench.c 66 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169
  1. /* tls_bench.c
  2. *
  3. * Copyright (C) 2006-2021 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. /*
  22. Example gcc build statement
  23. gcc -lwolfssl -lpthread -o tls_bench tls_bench.c
  24. ./tls_bench
  25. Or
  26. #include <examples/benchmark/tls_bench.h>
  27. bench_tls(args);
  28. */
  29. #ifdef HAVE_CONFIG_H
  30. #include <config.h>
  31. #endif
  32. #ifndef WOLFSSL_USER_SETTINGS
  33. #include <wolfssl/options.h>
  34. #endif
  35. #include <wolfssl/wolfcrypt/settings.h>
  36. #include <wolfssl/ssl.h>
  37. #include <wolfssl/wolfcrypt/hash.h> /* WC_MAX_DIGEST_SIZE */
  38. #include <wolfssl/test.h>
  39. #include <wolfssl/wolfio.h>
  40. #include <examples/benchmark/tls_bench.h>
  41. /* force certificate test buffers to be included via headers */
  42. #undef USE_CERT_BUFFERS_2048
  43. #define USE_CERT_BUFFERS_2048
  44. #undef USE_CERT_BUFFERS_256
  45. #define USE_CERT_BUFFERS_256
  46. #include <wolfssl/certs_test.h>
  47. #include <stdio.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50. #include <unistd.h>
  51. #include <sys/time.h>
  52. #include <errno.h>
  53. /* For testing no pthread support */
  54. #if 0
  55. #undef HAVE_PTHREAD
  56. #endif
  57. /* PTHREAD requires server and client enabled */
  58. #if defined(HAVE_PTHREAD) && (defined(NO_WOLFSSL_CLIENT) || defined(NO_WOLFSSL_SERVER))
  59. #undef HAVE_PTHREAD
  60. #endif
  61. #ifdef HAVE_PTHREAD
  62. #include <pthread.h>
  63. #endif
  64. #if 0
  65. #define BENCH_USE_NONBLOCK
  66. #endif
  67. /* Defaults for configuration parameters */
  68. #define BENCH_DEFAULT_HOST "localhost"
  69. #define BENCH_DEFAULT_PORT 11112
  70. #define NUM_THREAD_PAIRS 1 /* Thread pairs of server/client */
  71. #ifndef BENCH_RUNTIME_SEC
  72. #ifdef BENCH_EMBEDDED
  73. #define BENCH_RUNTIME_SEC 15
  74. #else
  75. #define BENCH_RUNTIME_SEC 1
  76. #endif
  77. #endif
  78. /* TLS packet size */
  79. #ifndef TEST_PACKET_SIZE
  80. #ifdef BENCH_EMBEDDED
  81. #define TEST_PACKET_SIZE (2 * 1024)
  82. #else
  83. #define TEST_PACKET_SIZE (16 * 1024)
  84. #endif
  85. #endif
  86. /* Total bytes to benchmark per connection */
  87. #ifndef TEST_MAX_SIZE
  88. #ifdef BENCH_EMBEDDED
  89. #define TEST_MAX_SIZE (16 * 1024)
  90. #else
  91. #define TEST_MAX_SIZE (128 * 1024)
  92. #endif
  93. #endif
  94. #ifdef WOLFSSL_DTLS
  95. #ifdef BENCH_EMBEDDED
  96. /* WOLFSSL_MAX_MTU in internal.h */
  97. #define TEST_DTLS_PACKET_SIZE (1500)
  98. #else
  99. /* MAX_UDP_SIZE in interna.h */
  100. #define TEST_DTLS_PACKET_SIZE (8092)
  101. #endif
  102. #endif
  103. /* In memory transfer buffer maximum size */
  104. /* Must be large enough to handle max TLS packet size plus max TLS header MAX_MSG_EXTRA */
  105. #define MEM_BUFFER_SZ (TEST_PACKET_SIZE + 38 + WC_MAX_DIGEST_SIZE)
  106. #define SHOW_VERBOSE 0 /* Default output is tab delimited format */
  107. #if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
  108. !defined(WOLFCRYPT_ONLY) && defined(USE_WOLFSSL_IO)
  109. /* shutdown message - nice signal to server, we are done */
  110. static const char* kShutdown = "shutdown";
  111. #ifndef NO_WOLFSSL_CLIENT
  112. PEDANTIC_EXTENSION static const char* kTestStr =
  113. "Biodiesel cupidatat marfa, cliche aute put a bird on it incididunt elit\n"
  114. "polaroid. Sunt tattooed bespoke reprehenderit. Sint twee organic id\n"
  115. "marfa. Commodo veniam ad esse gastropub. 3 wolf moon sartorial vero,\n"
  116. "plaid delectus biodiesel squid +1 vice. Post-ironic keffiyeh leggings\n"
  117. "selfies cray fap hoodie, forage anim. Carles cupidatat shoreditch, VHS\n"
  118. "small batch meggings kogi dolore food truck bespoke gastropub.\n"
  119. "\n"
  120. "Terry richardson adipisicing actually typewriter tumblr, twee whatever\n"
  121. "four loko you probably haven't heard of them high life. Messenger bag\n"
  122. "whatever tattooed deep v mlkshk. Brooklyn pinterest assumenda chillwave\n"
  123. "et, banksy ullamco messenger bag umami pariatur direct trade forage.\n"
  124. "Typewriter culpa try-hard, pariatur sint brooklyn meggings. Gentrify\n"
  125. "food truck next level, tousled irony non semiotics PBR ethical anim cred\n"
  126. "readymade. Mumblecore brunch lomo odd future, portland organic terry\n"
  127. "richardson elit leggings adipisicing ennui raw denim banjo hella. Godard\n"
  128. "mixtape polaroid, pork belly readymade organic cray typewriter helvetica\n"
  129. "four loko whatever street art yr farm-to-table.\n"
  130. "\n"
  131. "Vinyl keytar vice tofu. Locavore you probably haven't heard of them pug\n"
  132. "pickled, hella tonx labore truffaut DIY mlkshk elit cosby sweater sint\n"
  133. "et mumblecore. Elit swag semiotics, reprehenderit DIY sartorial nisi ugh\n"
  134. "nesciunt pug pork belly wayfarers selfies delectus. Ethical hoodie\n"
  135. "seitan fingerstache kale chips. Terry richardson artisan williamsburg,\n"
  136. "eiusmod fanny pack irony tonx ennui lo-fi incididunt tofu YOLO\n"
  137. "readymade. 8-bit sed ethnic beard officia. Pour-over iphone DIY butcher,\n"
  138. "ethnic art party qui letterpress nisi proident jean shorts mlkshk\n"
  139. "locavore.\n"
  140. "\n"
  141. "Narwhal flexitarian letterpress, do gluten-free voluptate next level\n"
  142. "banh mi tonx incididunt carles DIY. Odd future nulla 8-bit beard ut\n"
  143. "cillum pickled velit, YOLO officia you probably haven't heard of them\n"
  144. "trust fund gastropub. Nisi adipisicing tattooed, Austin mlkshk 90's\n"
  145. "small batch american apparel. Put a bird on it cosby sweater before they\n"
  146. "sold out pork belly kogi hella. Street art mollit sustainable polaroid,\n"
  147. "DIY ethnic ea pug beard dreamcatcher cosby sweater magna scenester nisi.\n"
  148. "Sed pork belly skateboard mollit, labore proident eiusmod. Sriracha\n"
  149. "excepteur cosby sweater, anim deserunt laborum eu aliquip ethical et\n"
  150. "neutra PBR selvage.\n"
  151. "\n"
  152. "Raw denim pork belly truffaut, irony plaid sustainable put a bird on it\n"
  153. "next level jean shorts exercitation. Hashtag keytar whatever, nihil\n"
  154. "authentic aliquip disrupt laborum. Tattooed selfies deserunt trust fund\n"
  155. "wayfarers. 3 wolf moon synth church-key sartorial, gastropub leggings\n"
  156. "tattooed. Labore high life commodo, meggings raw denim fingerstache pug\n"
  157. "trust fund leggings seitan forage. Nostrud ullamco duis, reprehenderit\n"
  158. "incididunt flannel sustainable helvetica pork belly pug banksy you\n"
  159. "probably haven't heard of them nesciunt farm-to-table. Disrupt nostrud\n"
  160. "mollit magna, sriracha sartorial helvetica.\n"
  161. "\n"
  162. "Nulla kogi reprehenderit, skateboard sustainable duis adipisicing viral\n"
  163. "ad fanny pack salvia. Fanny pack trust fund you probably haven't heard\n"
  164. "of them YOLO vice nihil. Keffiyeh cray lo-fi pinterest cardigan aliqua,\n"
  165. "reprehenderit aute. Culpa tousled williamsburg, marfa lomo actually anim\n"
  166. "skateboard. Iphone aliqua ugh, semiotics pariatur vero readymade\n"
  167. "organic. Marfa squid nulla, in laborum disrupt laboris irure gastropub.\n"
  168. "Veniam sunt food truck leggings, sint vinyl fap.\n"
  169. "\n"
  170. "Hella dolore pork belly, truffaut carles you probably haven't heard of\n"
  171. "them PBR helvetica in sapiente. Fashion axe ugh bushwick american\n"
  172. "apparel. Fingerstache sed iphone, jean shorts blue bottle nisi bushwick\n"
  173. "flexitarian officia veniam plaid bespoke fap YOLO lo-fi. Blog\n"
  174. "letterpress mumblecore, food truck id cray brooklyn cillum ad sed.\n"
  175. "Assumenda chambray wayfarers vinyl mixtape sustainable. VHS vinyl\n"
  176. "delectus, culpa williamsburg polaroid cliche swag church-key synth kogi\n"
  177. "magna pop-up literally. Swag thundercats ennui shoreditch vegan\n"
  178. "pitchfork neutra truffaut etsy, sed single-origin coffee craft beer.\n"
  179. "\n"
  180. "Odio letterpress brooklyn elit. Nulla single-origin coffee in occaecat\n"
  181. "meggings. Irony meggings 8-bit, chillwave lo-fi adipisicing cred\n"
  182. "dreamcatcher veniam. Put a bird on it irony umami, trust fund bushwick\n"
  183. "locavore kale chips. Sriracha swag thundercats, chillwave disrupt\n"
  184. "tousled beard mollit mustache leggings portland next level. Nihil esse\n"
  185. "est, skateboard art party etsy thundercats sed dreamcatcher ut iphone\n"
  186. "swag consectetur et. Irure skateboard banjo, nulla deserunt messenger\n"
  187. "bag dolor terry richardson sapiente.\n";
  188. #endif
  189. #if !defined(NO_DH)
  190. #define MIN_DHKEY_BITS 1024
  191. #if !defined(NO_WOLFSSL_SERVER)
  192. /* dh2048 p */
  193. static const unsigned char dhp[] =
  194. {
  195. 0xb0, 0xa1, 0x08, 0x06, 0x9c, 0x08, 0x13, 0xba, 0x59, 0x06, 0x3c, 0xbc, 0x30,
  196. 0xd5, 0xf5, 0x00, 0xc1, 0x4f, 0x44, 0xa7, 0xd6, 0xef, 0x4a, 0xc6, 0x25, 0x27,
  197. 0x1c, 0xe8, 0xd2, 0x96, 0x53, 0x0a, 0x5c, 0x91, 0xdd, 0xa2, 0xc2, 0x94, 0x84,
  198. 0xbf, 0x7d, 0xb2, 0x44, 0x9f, 0x9b, 0xd2, 0xc1, 0x8a, 0xc5, 0xbe, 0x72, 0x5c,
  199. 0xa7, 0xe7, 0x91, 0xe6, 0xd4, 0x9f, 0x73, 0x07, 0x85, 0x5b, 0x66, 0x48, 0xc7,
  200. 0x70, 0xfa, 0xb4, 0xee, 0x02, 0xc9, 0x3d, 0x9a, 0x4a, 0xda, 0x3d, 0xc1, 0x46,
  201. 0x3e, 0x19, 0x69, 0xd1, 0x17, 0x46, 0x07, 0xa3, 0x4d, 0x9f, 0x2b, 0x96, 0x17,
  202. 0x39, 0x6d, 0x30, 0x8d, 0x2a, 0xf3, 0x94, 0xd3, 0x75, 0xcf, 0xa0, 0x75, 0xe6,
  203. 0xf2, 0x92, 0x1f, 0x1a, 0x70, 0x05, 0xaa, 0x04, 0x83, 0x57, 0x30, 0xfb, 0xda,
  204. 0x76, 0x93, 0x38, 0x50, 0xe8, 0x27, 0xfd, 0x63, 0xee, 0x3c, 0xe5, 0xb7, 0xc8,
  205. 0x09, 0xae, 0x6f, 0x50, 0x35, 0x8e, 0x84, 0xce, 0x4a, 0x00, 0xe9, 0x12, 0x7e,
  206. 0x5a, 0x31, 0xd7, 0x33, 0xfc, 0x21, 0x13, 0x76, 0xcc, 0x16, 0x30, 0xdb, 0x0c,
  207. 0xfc, 0xc5, 0x62, 0xa7, 0x35, 0xb8, 0xef, 0xb7, 0xb0, 0xac, 0xc0, 0x36, 0xf6,
  208. 0xd9, 0xc9, 0x46, 0x48, 0xf9, 0x40, 0x90, 0x00, 0x2b, 0x1b, 0xaa, 0x6c, 0xe3,
  209. 0x1a, 0xc3, 0x0b, 0x03, 0x9e, 0x1b, 0xc2, 0x46, 0xe4, 0x48, 0x4e, 0x22, 0x73,
  210. 0x6f, 0xc3, 0x5f, 0xd4, 0x9a, 0xd6, 0x30, 0x07, 0x48, 0xd6, 0x8c, 0x90, 0xab,
  211. 0xd4, 0xf6, 0xf1, 0xe3, 0x48, 0xd3, 0x58, 0x4b, 0xa6, 0xb9, 0xcd, 0x29, 0xbf,
  212. 0x68, 0x1f, 0x08, 0x4b, 0x63, 0x86, 0x2f, 0x5c, 0x6b, 0xd6, 0xb6, 0x06, 0x65,
  213. 0xf7, 0xa6, 0xdc, 0x00, 0x67, 0x6b, 0xbb, 0xc3, 0xa9, 0x41, 0x83, 0xfb, 0xc7,
  214. 0xfa, 0xc8, 0xe2, 0x1e, 0x7e, 0xaf, 0x00, 0x3f, 0x93
  215. };
  216. /* dh2048 g */
  217. static const unsigned char dhg[] =
  218. {
  219. 0x02,
  220. };
  221. #endif /* !NO_WOLFSSL_SERVER */
  222. #endif /* !NO_DH */
  223. #ifdef WOLFSSL_TLS13
  224. struct group_info {
  225. word16 group;
  226. const char *name;
  227. };
  228. static struct group_info groups[] = {
  229. { WOLFSSL_ECC_SECP160K1, "ECC_SECP160K1" },
  230. { WOLFSSL_ECC_SECP160R1, "ECC_SECP160R1" },
  231. { WOLFSSL_ECC_SECP160R2, "ECC_SECP160R2" },
  232. { WOLFSSL_ECC_SECP192K1, "ECC_SECP192K1" },
  233. { WOLFSSL_ECC_SECP192R1, "ECC_SECP192R1" },
  234. { WOLFSSL_ECC_SECP224K1, "ECC_SECP224K1" },
  235. { WOLFSSL_ECC_SECP224R1, "ECC_SECP224R1" },
  236. { WOLFSSL_ECC_SECP256K1, "ECC_SECP256K1" },
  237. { WOLFSSL_ECC_SECP256R1, "ECC_SECP256R1" },
  238. { WOLFSSL_ECC_SECP384R1, "ECC_SECP384R1" },
  239. { WOLFSSL_ECC_SECP521R1, "ECC_SECP521R1" },
  240. { WOLFSSL_ECC_BRAINPOOLP256R1, "ECC_BRAINPOOLP256R1" },
  241. { WOLFSSL_ECC_BRAINPOOLP384R1, "ECC_BRAINPOOLP384R1" },
  242. { WOLFSSL_ECC_BRAINPOOLP512R1, "ECC_BRAINPOOLP512R1" },
  243. { WOLFSSL_ECC_X25519, "ECC_X25519" },
  244. { WOLFSSL_ECC_X448, "ECC_X448" },
  245. { WOLFSSL_FFDHE_2048, "FFDHE_2048" },
  246. { WOLFSSL_FFDHE_3072, "FFDHE_3072" },
  247. { WOLFSSL_FFDHE_4096, "FFDHE_4096" },
  248. { WOLFSSL_FFDHE_6144, "FFDHE_6144" },
  249. { WOLFSSL_FFDHE_8192, "FFDHE_8192" },
  250. #ifdef HAVE_LIBOQS
  251. { WOLFSSL_NTRU_HPS_LEVEL1, "NTRU_HPS_LEVEL1" },
  252. { WOLFSSL_NTRU_HPS_LEVEL3, "NTRU_HPS_LEVEL3" },
  253. { WOLFSSL_NTRU_HPS_LEVEL5, "NTRU_HPS_LEVEL5" },
  254. { WOLFSSL_NTRU_HRSS_LEVEL3, "NTRU_HRSS_LEVEL3" },
  255. { WOLFSSL_SABER_LEVEL1, "SABER_LEVEL1" },
  256. { WOLFSSL_SABER_LEVEL3, "SABER_LEVEL3" },
  257. { WOLFSSL_SABER_LEVEL5, "SABER_LEVEL5" },
  258. { WOLFSSL_KYBER_LEVEL1, "KYBER_LEVEL1" },
  259. { WOLFSSL_KYBER_LEVEL3, "KYBER_LEVEL3" },
  260. { WOLFSSL_KYBER_LEVEL5, "KYBER_LEVEL5" },
  261. { WOLFSSL_KYBER_90S_LEVEL1, "KYBER_90S_LEVEL1" },
  262. { WOLFSSL_KYBER_90S_LEVEL3, "KYBER_90S_LEVEL3" },
  263. { WOLFSSL_KYBER_90S_LEVEL5, "KYBER_90S_LEVEL5" },
  264. { WOLFSSL_P256_NTRU_HPS_LEVEL1, "P256_NTRU_HPS_LEVEL1" },
  265. { WOLFSSL_P384_NTRU_HPS_LEVEL3, "P384_NTRU_HPS_LEVEL3" },
  266. { WOLFSSL_P521_NTRU_HPS_LEVEL5, "P521_NTRU_HPS_LEVEL5" },
  267. { WOLFSSL_P384_NTRU_HRSS_LEVEL3, "P384_NTRU_HRSS_LEVEL3" },
  268. { WOLFSSL_P256_SABER_LEVEL1, "P256_SABER_LEVEL1" },
  269. { WOLFSSL_P384_SABER_LEVEL3, "P384_SABER_LEVEL3" },
  270. { WOLFSSL_P521_SABER_LEVEL5, "P521_SABER_LEVEL5" },
  271. { WOLFSSL_P256_KYBER_LEVEL1, "P256_KYBER_LEVEL1" },
  272. { WOLFSSL_P384_KYBER_LEVEL3, "P384_KYBER_LEVEL3" },
  273. { WOLFSSL_P521_KYBER_LEVEL5, "P521_KYBER_LEVEL5" },
  274. { WOLFSSL_P256_KYBER_90S_LEVEL1, "P256_KYBER_90S_LEVEL1" },
  275. { WOLFSSL_P384_KYBER_90S_LEVEL3, "P384_KYBER_90S_LEVEL3" },
  276. { WOLFSSL_P521_KYBER_90S_LEVEL5, "P521_KYBER_90S_LEVEL5" },
  277. #endif
  278. { 0, NULL }
  279. };
  280. #endif /* WOLFSSL_TLS13 */
  281. #ifdef HAVE_PTHREAD
  282. typedef struct {
  283. unsigned char buf[MEM_BUFFER_SZ];
  284. int write_bytes;
  285. int write_idx;
  286. int read_bytes;
  287. int read_idx;
  288. pthread_t tid;
  289. pthread_mutex_t mutex;
  290. pthread_cond_t cond;
  291. int done;
  292. } memBuf_t;
  293. #endif
  294. typedef struct {
  295. double connTime;
  296. double rxTime;
  297. double txTime;
  298. int connCount;
  299. int rxTotal;
  300. int txTotal;
  301. } stats_t;
  302. typedef struct {
  303. int shutdown;
  304. int sockFd;
  305. int ret;
  306. } side_t;
  307. typedef struct {
  308. const char* cipher;
  309. word16 group;
  310. const char* host;
  311. word32 port;
  312. int packetSize; /* The data payload size in the packet */
  313. int maxSize;
  314. int runTimeSec;
  315. int showPeerInfo;
  316. int showVerbose;
  317. #ifndef NO_WOLFSSL_SERVER
  318. int listenFd;
  319. #endif
  320. #ifdef WOLFSSL_DTLS
  321. int doDTLS;
  322. struct sockaddr_in serverAddr;
  323. struct sockaddr_in clientAddr;
  324. #ifdef HAVE_PTHREAD
  325. int serverReady;
  326. int clientOrserverOnly;
  327. pthread_mutex_t dtls_mutex;
  328. pthread_cond_t dtls_cond;
  329. #endif
  330. #endif
  331. side_t client;
  332. side_t server;
  333. #ifdef HAVE_PTHREAD
  334. int useLocalMem;
  335. /* client messages to server in memory */
  336. memBuf_t to_server;
  337. /* server messages to client in memory */
  338. memBuf_t to_client;
  339. /* Indicates that the server is ready for connection */
  340. int serverListening;
  341. #endif
  342. /* server */
  343. stats_t server_stats;
  344. /* client */
  345. stats_t client_stats;
  346. } info_t;
  347. /* Global vars for argument parsing */
  348. int myoptind = 0;
  349. char* myoptarg = NULL;
  350. #ifdef WOLFSSL_DTLS
  351. int DoneHandShake = 0;
  352. #endif
  353. static double gettime_secs(int reset)
  354. {
  355. struct timeval tv;
  356. gettimeofday(&tv, 0);
  357. (void)reset;
  358. return (double)tv.tv_sec + (double)tv.tv_usec / 1000000;
  359. }
  360. #ifdef HAVE_PTHREAD
  361. /* server send callback */
  362. static int ServerMemSend(info_t* info, char* buf, int sz)
  363. {
  364. pthread_mutex_lock(&info->to_client.mutex);
  365. #ifndef BENCH_USE_NONBLOCK
  366. /* check for overflow */
  367. if (info->to_client.write_idx + sz > MEM_BUFFER_SZ) {
  368. pthread_mutex_unlock(&info->to_client.mutex);
  369. fprintf(stderr, "ServerMemSend overflow\n");
  370. return -1;
  371. }
  372. #else
  373. if (info->to_client.write_idx + sz > MEM_BUFFER_SZ)
  374. sz = MEM_BUFFER_SZ - info->to_client.write_idx;
  375. #endif
  376. XMEMCPY(&info->to_client.buf[info->to_client.write_idx], buf, sz);
  377. info->to_client.write_idx += sz;
  378. info->to_client.write_bytes += sz;
  379. pthread_cond_signal(&info->to_client.cond);
  380. pthread_mutex_unlock(&info->to_client.mutex);
  381. #ifdef BENCH_USE_NONBLOCK
  382. if (sz == 0)
  383. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  384. #endif
  385. return sz;
  386. }
  387. /* server recv callback */
  388. static int ServerMemRecv(info_t* info, char* buf, int sz)
  389. {
  390. pthread_mutex_lock(&info->to_server.mutex);
  391. #ifndef BENCH_USE_NONBLOCK
  392. while (info->to_server.write_idx - info->to_server.read_idx < sz && !info->to_client.done)
  393. pthread_cond_wait(&info->to_server.cond, &info->to_server.mutex);
  394. #else
  395. if (info->to_server.write_idx - info->to_server.read_idx < sz)
  396. sz = info->to_server.write_idx - info->to_server.read_idx;
  397. #endif
  398. XMEMCPY(buf, &info->to_server.buf[info->to_server.read_idx], sz);
  399. info->to_server.read_idx += sz;
  400. info->to_server.read_bytes += sz;
  401. /* if the rx has caught up with pending then reset buffer positions */
  402. if (info->to_server.read_bytes == info->to_server.write_bytes) {
  403. info->to_server.read_bytes = info->to_server.read_idx = 0;
  404. info->to_server.write_bytes = info->to_server.write_idx = 0;
  405. }
  406. pthread_mutex_unlock(&info->to_server.mutex);
  407. if (info->to_client.done != 0)
  408. return -1;
  409. #ifdef BENCH_USE_NONBLOCK
  410. if (sz == 0)
  411. return WOLFSSL_CBIO_ERR_WANT_READ;
  412. #endif
  413. return sz;
  414. }
  415. /* client send callback */
  416. static int ClientMemSend(info_t* info, char* buf, int sz)
  417. {
  418. pthread_mutex_lock(&info->to_server.mutex);
  419. #ifndef BENCH_USE_NONBLOCK
  420. /* check for overflow */
  421. if (info->to_server.write_idx + sz > MEM_BUFFER_SZ) {
  422. fprintf(stderr, "ClientMemSend overflow %d %d %d\n", info->to_server.write_idx, sz, MEM_BUFFER_SZ);
  423. pthread_mutex_unlock(&info->to_server.mutex);
  424. return -1;
  425. }
  426. #else
  427. if (info->to_server.write_idx + sz > MEM_BUFFER_SZ)
  428. sz = MEM_BUFFER_SZ - info->to_server.write_idx;
  429. #endif
  430. XMEMCPY(&info->to_server.buf[info->to_server.write_idx], buf, sz);
  431. info->to_server.write_idx += sz;
  432. info->to_server.write_bytes += sz;
  433. pthread_cond_signal(&info->to_server.cond);
  434. pthread_mutex_unlock(&info->to_server.mutex);
  435. #ifdef BENCH_USE_NONBLOCK
  436. if (sz == 0)
  437. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  438. #endif
  439. return sz;
  440. }
  441. /* client recv callback */
  442. static int ClientMemRecv(info_t* info, char* buf, int sz)
  443. {
  444. pthread_mutex_lock(&info->to_client.mutex);
  445. #ifndef BENCH_USE_NONBLOCK
  446. while (info->to_client.write_idx - info->to_client.read_idx < sz)
  447. pthread_cond_wait(&info->to_client.cond, &info->to_client.mutex);
  448. #else
  449. if (info->to_client.write_idx - info->to_client.read_idx < sz)
  450. sz = info->to_client.write_idx - info->to_client.read_idx;
  451. #endif
  452. XMEMCPY(buf, &info->to_client.buf[info->to_client.read_idx], sz);
  453. info->to_client.read_idx += sz;
  454. info->to_client.read_bytes += sz;
  455. /* if the rx has caught up with pending then reset buffer positions */
  456. if (info->to_client.read_bytes == info->to_client.write_bytes) {
  457. info->to_client.read_bytes = info->to_client.read_idx = 0;
  458. info->to_client.write_bytes = info->to_client.write_idx = 0;
  459. }
  460. pthread_mutex_unlock(&info->to_client.mutex);
  461. #ifdef BENCH_USE_NONBLOCK
  462. if (sz == 0)
  463. return WOLFSSL_CBIO_ERR_WANT_READ;
  464. #endif
  465. return sz;
  466. }
  467. #endif /* HAVE_PTHREAD */
  468. static int SocketRecv(int sockFd, char* buf, int sz)
  469. {
  470. int recvd = (int)recv(sockFd, buf, sz, 0);
  471. if (recvd == -1) {
  472. switch (errno) {
  473. #if EAGAIN != SOCKET_EWOULDBLOCK
  474. case EAGAIN: /* EAGAIN == EWOULDBLOCK on some systems, but not others */
  475. #endif
  476. case SOCKET_EWOULDBLOCK:
  477. return WOLFSSL_CBIO_ERR_WANT_READ;
  478. case SOCKET_ECONNRESET:
  479. return WOLFSSL_CBIO_ERR_CONN_RST;
  480. case SOCKET_EINTR:
  481. return WOLFSSL_CBIO_ERR_ISR;
  482. case SOCKET_ECONNREFUSED: /* DTLS case */
  483. return WOLFSSL_CBIO_ERR_WANT_READ;
  484. case SOCKET_ECONNABORTED:
  485. return WOLFSSL_CBIO_ERR_CONN_CLOSE;
  486. default:
  487. return WOLFSSL_CBIO_ERR_GENERAL;
  488. }
  489. }
  490. else if (recvd == 0) {
  491. return WOLFSSL_CBIO_ERR_CONN_CLOSE;
  492. }
  493. return recvd;
  494. }
  495. static int SocketSend(int sockFd, char* buf, int sz)
  496. {
  497. int sent = (int)send(sockFd, buf, sz, 0);
  498. if (sent == -1) {
  499. switch (errno) {
  500. #if EAGAIN != SOCKET_EWOULDBLOCK
  501. case EAGAIN: /* EAGAIN == EWOULDBLOCK on some systems, but not others */
  502. #endif
  503. case SOCKET_EWOULDBLOCK:
  504. return WOLFSSL_CBIO_ERR_WANT_READ;
  505. case SOCKET_ECONNRESET:
  506. return WOLFSSL_CBIO_ERR_CONN_RST;
  507. case SOCKET_EINTR:
  508. return WOLFSSL_CBIO_ERR_ISR;
  509. case SOCKET_EPIPE:
  510. return WOLFSSL_CBIO_ERR_CONN_CLOSE;
  511. default:
  512. return WOLFSSL_CBIO_ERR_GENERAL;
  513. }
  514. }
  515. else if (sent == 0) {
  516. return 0;
  517. }
  518. return sent;
  519. }
  520. #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
  521. static int ReceiveFrom(WOLFSSL *ssl, int sd, char *buf, int sz)
  522. {
  523. int recvd;
  524. int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl);
  525. struct sockaddr peer;
  526. socklen_t peerSz = 0;
  527. if (DoneHandShake) dtls_timeout = 0;
  528. if (!wolfSSL_get_using_nonblock(ssl)) {
  529. struct timeval timeout;
  530. XMEMSET(&timeout, 0, sizeof(timeout));
  531. timeout.tv_sec = dtls_timeout;
  532. if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout,
  533. sizeof(timeout)) != 0) {
  534. fprintf(stderr, "setsockopt rcvtimeo failed\n");
  535. }
  536. }
  537. recvd = (int)recvfrom(sd, buf, sz, 0, (SOCKADDR*)&peer, &peerSz);
  538. if (recvd < 0) {
  539. if (errno == SOCKET_EWOULDBLOCK || errno == SOCKET_EAGAIN) {
  540. if (wolfSSL_dtls_get_using_nonblock(ssl)) {
  541. return WOLFSSL_CBIO_ERR_WANT_READ;
  542. }
  543. else {
  544. return WOLFSSL_CBIO_ERR_TIMEOUT;
  545. }
  546. }
  547. else if (errno == SOCKET_ECONNRESET) {
  548. return WOLFSSL_CBIO_ERR_CONN_RST;
  549. }
  550. else if (errno == SOCKET_EINTR) {
  551. return WOLFSSL_CBIO_ERR_ISR;
  552. }
  553. else if (errno == SOCKET_ECONNREFUSED) {
  554. return WOLFSSL_CBIO_ERR_WANT_READ;
  555. }
  556. else {
  557. return WOLFSSL_CBIO_ERR_GENERAL;
  558. }
  559. }
  560. else {
  561. if (recvd == 0) {
  562. return WOLFSSL_CBIO_ERR_CONN_CLOSE;
  563. }
  564. }
  565. return recvd;
  566. }
  567. #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_SERVER */
  568. #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_CLIENT)
  569. static int SendTo(int sd, char *buf, int sz, const struct sockaddr *peer,
  570. socklen_t peerSz)
  571. {
  572. int sent;
  573. sent = (int)sendto(sd, buf, sz, 0, peer, peerSz);
  574. if (sent < 0) {
  575. if (errno == SOCKET_EWOULDBLOCK || errno == SOCKET_EAGAIN) {
  576. return WOLFSSL_CBIO_ERR_WANT_WRITE;
  577. }
  578. else if (errno == SOCKET_ECONNRESET) {
  579. return WOLFSSL_CBIO_ERR_CONN_RST;
  580. }
  581. else if (errno == SOCKET_EINTR) {
  582. return WOLFSSL_CBIO_ERR_ISR;
  583. }
  584. else if (errno == SOCKET_EPIPE) {
  585. return WOLFSSL_CBIO_ERR_CONN_CLOSE;
  586. }
  587. else {
  588. return WOLFSSL_CBIO_ERR_GENERAL;
  589. }
  590. }
  591. return sent;
  592. }
  593. static int myDoneHsCb(WOLFSSL* ssl, void* user_ctx)
  594. {
  595. (void) ssl;
  596. (void) user_ctx;
  597. DoneHandShake = 1;
  598. return 1;
  599. }
  600. #endif /* WOLFSSL_DTLS && !NO_WOLFSSL_CLIENT */
  601. #ifndef NO_WOLFSSL_SERVER
  602. static int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  603. {
  604. info_t* info = (info_t*)ctx;
  605. (void)ssl;
  606. #ifdef HAVE_PTHREAD
  607. if (info->useLocalMem)
  608. return ServerMemSend(info, buf, sz);
  609. #endif
  610. #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_CLIENT)
  611. if (info->doDTLS) {
  612. return SendTo(info->server.sockFd, buf, sz,
  613. (const struct sockaddr*)&info->clientAddr, sizeof(info->clientAddr));
  614. } else
  615. #endif
  616. return SocketSend(info->server.sockFd, buf, sz);
  617. }
  618. static int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  619. {
  620. info_t* info = (info_t*)ctx;
  621. (void)ssl;
  622. #ifdef HAVE_PTHREAD
  623. if (info->useLocalMem)
  624. return ServerMemRecv(info, buf, sz);
  625. #endif
  626. #ifdef WOLFSSL_DTLS
  627. if (info->doDTLS) {
  628. return ReceiveFrom(ssl, info->server.sockFd, buf, sz);
  629. } else
  630. #endif
  631. return SocketRecv(info->server.sockFd, buf, sz);
  632. }
  633. #endif /* !NO_WOLFSSL_SERVER */
  634. #ifndef NO_WOLFSSL_CLIENT
  635. static int ClientSend(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  636. {
  637. info_t* info = (info_t*)ctx;
  638. (void)ssl;
  639. #ifdef HAVE_PTHREAD
  640. if (info->useLocalMem)
  641. return ClientMemSend(info, buf, sz);
  642. #endif
  643. #ifdef WOLFSSL_DTLS
  644. if (info->doDTLS) {
  645. return SendTo(info->client.sockFd, buf, sz,
  646. (const struct sockaddr*)&info->serverAddr, sizeof(info->serverAddr));
  647. } else
  648. #endif
  649. return SocketSend(info->client.sockFd, buf, sz);
  650. }
  651. static int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx)
  652. {
  653. info_t* info = (info_t*)ctx;
  654. (void)ssl;
  655. #ifdef HAVE_PTHREAD
  656. if (info->useLocalMem)
  657. return ClientMemRecv(info, buf, sz);
  658. #endif
  659. #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
  660. if (info->doDTLS) {
  661. return ReceiveFrom(ssl, info->client.sockFd, buf, sz);
  662. } else
  663. #endif
  664. return SocketRecv(info->client.sockFd, buf, sz);
  665. }
  666. #endif /* !NO_WOLFSSL_CLIENT */
  667. static void CloseAndCleanupSocket(int* sockFd)
  668. {
  669. if (*sockFd != -1) {
  670. close(*sockFd);
  671. *sockFd = -1;
  672. }
  673. #ifdef WOLFSSL_DTLS
  674. DoneHandShake = 0;
  675. #endif
  676. }
  677. #ifdef BENCH_USE_NONBLOCK
  678. static int SetSocketNonBlocking(int sockFd)
  679. {
  680. int flags = fcntl(sockFd, F_GETFL, 0);
  681. if (flags < 0) {
  682. fprintf(stderr, "fcntl get failed\n");
  683. return -1;
  684. }
  685. flags = fcntl(sockFd, F_SETFL, flags | O_NONBLOCK);
  686. if (flags < 0) {
  687. fprintf(stderr, "fcntl set failed\n");
  688. return -1;
  689. }
  690. return 0;
  691. }
  692. #endif
  693. #ifndef NO_WOLFSSL_CLIENT
  694. static int SetupSocketAndConnect(info_t* info, const char* host,
  695. word32 port)
  696. {
  697. struct sockaddr_in servAddr;
  698. struct hostent* entry;
  699. /* Setup server address */
  700. XMEMSET(&servAddr, 0, sizeof(servAddr));
  701. servAddr.sin_family = AF_INET;
  702. servAddr.sin_port = htons(port);
  703. /* Resolve host */
  704. entry = gethostbyname(host);
  705. if (entry) {
  706. XMEMCPY(&servAddr.sin_addr.s_addr, entry->h_addr_list[0],
  707. entry->h_length);
  708. }
  709. else {
  710. servAddr.sin_addr.s_addr = inet_addr(host);
  711. }
  712. #ifdef WOLFSSL_DTLS
  713. if (info->doDTLS) {
  714. /* Create the SOCK_DGRAM socket type is implemented on the User
  715. * Datagram Protocol/Internet Protocol(UDP/IP protocol).*/
  716. if ((info->client.sockFd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  717. fprintf(stderr, "ERROR: failed to create the SOCK_DGRAM socket\n");
  718. return -1;
  719. }
  720. XMEMCPY(&info->serverAddr, &servAddr, sizeof(servAddr));
  721. } else {
  722. #endif
  723. /* Create a socket that uses an Internet IPv4 address,
  724. * Sets the socket to be stream based (TCP),
  725. * 0 means choose the default protocol. */
  726. if ((info->client.sockFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  727. fprintf(stderr, "ERROR: failed to create the socket\n");
  728. return -1;
  729. }
  730. /* Connect to the server */
  731. #ifdef HAVE_PTHREAD
  732. while ((info->serverListening == 0) && (info->server.shutdown == 0)) {
  733. if (info->showVerbose) {
  734. fprintf(stderr, "Waiting for server to listen...\n");
  735. }
  736. XSLEEP_MS(1);
  737. }
  738. #endif
  739. if (info->server.shutdown == 1) {
  740. fprintf(stderr, "ERROR: server side has shutdown\n");
  741. return -1;
  742. }
  743. if (connect(info->client.sockFd, (struct sockaddr*)&servAddr,
  744. sizeof(servAddr)) == -1) {
  745. fprintf(stderr, "ERROR: failed to connect\n");
  746. return -1;
  747. }
  748. #ifdef WOLFSSL_DTLS
  749. }
  750. #endif
  751. #ifdef BENCH_USE_NONBLOCK
  752. if (SetSocketNonBlocking(info->client.sockFd) != 0) {
  753. return -1;
  754. }
  755. #endif
  756. if (info->showVerbose) {
  757. fprintf(stderr, "Connected to %s on port %d\n", host, port);
  758. }
  759. return 0;
  760. }
  761. static int bench_tls_client(info_t* info)
  762. {
  763. byte *writeBuf = NULL, *readBuf = NULL;
  764. double start, total = 0;
  765. int ret, readBufSz;
  766. WOLFSSL_CTX* cli_ctx = NULL;
  767. WOLFSSL* cli_ssl = NULL;
  768. int haveShownPeerInfo = 0;
  769. int tls13 = XSTRNCMP(info->cipher, "TLS13", 5) == 0;
  770. int total_sz;
  771. total = gettime_secs(0);
  772. /* set up client */
  773. #ifdef WOLFSSL_DTLS
  774. if(info->doDTLS) {
  775. if (tls13) return WOLFSSL_SUCCESS;
  776. cli_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method());
  777. } else
  778. #endif
  779. #ifdef WOLFSSL_TLS13
  780. if (tls13)
  781. cli_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  782. #endif
  783. if (!tls13)
  784. #ifdef WOLFSSL_DTLS
  785. if(!info->doDTLS)
  786. #endif
  787. #if !defined(WOLFSSL_TLS13)
  788. cli_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method());
  789. #elif !defined(WOLFSSL_NO_TLS12)
  790. cli_ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method());
  791. #endif
  792. if (cli_ctx == NULL) {
  793. fprintf(stderr, "error creating ctx\n");
  794. ret = MEMORY_E; goto exit;
  795. }
  796. #ifndef NO_CERTS
  797. #ifdef HAVE_ECC
  798. if (XSTRSTR(info->cipher, "ECDSA")) {
  799. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_ecc_cert_der_256,
  800. sizeof_ca_ecc_cert_der_256, WOLFSSL_FILETYPE_ASN1);
  801. }
  802. else
  803. #endif
  804. {
  805. ret = wolfSSL_CTX_load_verify_buffer(cli_ctx, ca_cert_der_2048,
  806. sizeof_ca_cert_der_2048, WOLFSSL_FILETYPE_ASN1);
  807. }
  808. if (ret != WOLFSSL_SUCCESS) {
  809. fprintf(stderr, "error loading CA\n");
  810. goto exit;
  811. }
  812. #endif
  813. wolfSSL_CTX_SetIOSend(cli_ctx, ClientSend);
  814. wolfSSL_CTX_SetIORecv(cli_ctx, ClientRecv);
  815. /* set cipher suite */
  816. ret = wolfSSL_CTX_set_cipher_list(cli_ctx, info->cipher);
  817. if (ret != WOLFSSL_SUCCESS) {
  818. fprintf(stderr, "error setting cipher suite\n");
  819. goto exit;
  820. }
  821. #ifndef NO_DH
  822. ret = wolfSSL_CTX_SetMinDhKey_Sz(cli_ctx, MIN_DHKEY_BITS);
  823. if (ret != WOLFSSL_SUCCESS) {
  824. fprintf(stderr, "Error setting minimum DH key size\n");
  825. goto exit;
  826. }
  827. #endif
  828. /* Allocate and initialize a packet sized buffer */
  829. writeBuf = (unsigned char*)XMALLOC(info->packetSize, NULL,
  830. DYNAMIC_TYPE_TMP_BUFFER);
  831. if (writeBuf == NULL) {
  832. fprintf(stderr, "failed to allocate write memory\n");
  833. ret = MEMORY_E; goto exit;
  834. }
  835. /* Allocate read buffer */
  836. readBufSz = info->packetSize;
  837. readBuf = (unsigned char*)XMALLOC(readBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  838. if (readBuf == NULL) {
  839. fprintf(stderr, "failed to allocate read memory\n");
  840. ret = MEMORY_E; goto exit;
  841. }
  842. /* BENCHMARK CONNECTIONS LOOP */
  843. while (!info->client.shutdown) {
  844. int writeSz = info->packetSize;
  845. #ifdef BENCH_USE_NONBLOCK
  846. int err;
  847. #endif
  848. #ifdef HAVE_PTHREAD
  849. if (!info->useLocalMem)
  850. #endif
  851. {
  852. /* Setup socket and connection */
  853. ret = SetupSocketAndConnect(info, info->host, info->port);
  854. if (ret != 0) goto exit;
  855. }
  856. cli_ssl = wolfSSL_new(cli_ctx);
  857. if (cli_ssl == NULL) {
  858. fprintf(stderr, "error creating client object\n");
  859. goto exit;
  860. }
  861. #ifdef WOLFSSL_TLS13
  862. if (info->group != 0) {
  863. ret = wolfSSL_UseKeyShare(cli_ssl, info->group);
  864. if (ret != WOLFSSL_SUCCESS) {
  865. fprintf(stderr, "error setting client key share.\n");
  866. goto exit;
  867. }
  868. }
  869. #endif
  870. #ifdef WOLFSSL_DTLS
  871. if (info->doDTLS) {
  872. ret = wolfSSL_dtls_set_peer(cli_ssl, &info->serverAddr,
  873. sizeof(info->serverAddr));
  874. if (ret != WOLFSSL_SUCCESS) {
  875. fprintf(stderr, "error setting dtls peer\n");
  876. goto exit;
  877. }
  878. ret = wolfSSL_SetHsDoneCb(cli_ssl, myDoneHsCb, NULL);
  879. if (ret != WOLFSSL_SUCCESS) {
  880. fprintf(stderr, "error handshake done callback\n");
  881. goto exit;
  882. }
  883. }
  884. #endif
  885. wolfSSL_SetIOReadCtx(cli_ssl, info);
  886. wolfSSL_SetIOWriteCtx(cli_ssl, info);
  887. #if defined(HAVE_PTHREAD) && defined(WOLFSSL_DTLS)
  888. /* synchronize with server */
  889. if (info->doDTLS && !info->clientOrserverOnly) {
  890. pthread_mutex_lock(&info->dtls_mutex);
  891. if (info->serverReady != 1) {
  892. pthread_cond_wait(&info->dtls_cond, &info->dtls_mutex);
  893. }
  894. /* for next loop */
  895. info->serverReady = 0;
  896. pthread_mutex_unlock(&info->dtls_mutex);
  897. }
  898. #endif
  899. /* perform connect */
  900. start = gettime_secs(1);
  901. #ifndef BENCH_USE_NONBLOCK
  902. ret = wolfSSL_connect(cli_ssl);
  903. #else
  904. do
  905. {
  906. ret = wolfSSL_connect(cli_ssl);
  907. err = wolfSSL_get_error(cli_ssl, ret);
  908. }
  909. while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  910. #endif
  911. start = gettime_secs(0) - start;
  912. if (ret != WOLFSSL_SUCCESS) {
  913. fprintf(stderr, "error connecting client\n");
  914. ret = wolfSSL_get_error(cli_ssl, ret);
  915. goto exit;
  916. }
  917. info->client_stats.connTime += start;
  918. info->client_stats.connCount++;
  919. if ((info->showPeerInfo) && (!haveShownPeerInfo)) {
  920. haveShownPeerInfo = 1;
  921. showPeer(cli_ssl);
  922. }
  923. /* check for run time completion and issue shutdown */
  924. if (gettime_secs(0) - total >= info->runTimeSec) {
  925. info->client.shutdown = 1;
  926. writeSz = (int)XSTRLEN(kShutdown) + 1;
  927. XMEMCPY(writeBuf, kShutdown, writeSz); /* include null term */
  928. if (info->showVerbose) {
  929. fprintf(stderr, "Sending shutdown\n");
  930. }
  931. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  932. if (ret < 0) {
  933. fprintf(stderr, "error on client write\n");
  934. ret = wolfSSL_get_error(cli_ssl, ret);
  935. goto exit;
  936. }
  937. }
  938. else {
  939. XMEMSET(writeBuf, 0, info->packetSize);
  940. XSTRNCPY((char*)writeBuf, kTestStr, info->packetSize);
  941. }
  942. /* write / read echo loop */
  943. ret = 0;
  944. total_sz = 0;
  945. while (ret == 0 && total_sz < info->maxSize && !info->client.shutdown) {
  946. /* write test message to server */
  947. start = gettime_secs(1);
  948. #ifndef BENCH_USE_NONBLOCK
  949. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  950. #else
  951. do {
  952. ret = wolfSSL_write(cli_ssl, writeBuf, writeSz);
  953. err = wolfSSL_get_error(cli_ssl, ret);
  954. }
  955. while (err == WOLFSSL_ERROR_WANT_WRITE);
  956. #endif
  957. info->client_stats.txTime += gettime_secs(0) - start;
  958. if (ret < 0) {
  959. fprintf(stderr, "error on client write\n");
  960. ret = wolfSSL_get_error(cli_ssl, ret);
  961. goto exit;
  962. }
  963. info->client_stats.txTotal += ret;
  964. total_sz += ret;
  965. /* read echo of message from server */
  966. XMEMSET(readBuf, 0, readBufSz);
  967. start = gettime_secs(1);
  968. #ifndef BENCH_USE_NONBLOCK
  969. ret = wolfSSL_read(cli_ssl, readBuf, readBufSz);
  970. #else
  971. do {
  972. ret = wolfSSL_read(cli_ssl, readBuf, readBufSz);
  973. err = wolfSSL_get_error(cli_ssl, ret);
  974. }
  975. while (err == WOLFSSL_ERROR_WANT_READ);
  976. #endif
  977. info->client_stats.rxTime += gettime_secs(0) - start;
  978. if (ret < 0) {
  979. fprintf(stderr, "error on client read\n");
  980. ret = wolfSSL_get_error(cli_ssl, ret);
  981. goto exit;
  982. }
  983. info->client_stats.rxTotal += ret;
  984. ret = 0; /* reset return code */
  985. /* validate echo */
  986. if (XMEMCMP((char*)writeBuf, (char*)readBuf, writeSz) != 0) {
  987. fprintf(stderr, "echo check failed!\n");
  988. ret = wolfSSL_get_error(cli_ssl, ret);
  989. goto exit;
  990. }
  991. }
  992. CloseAndCleanupSocket(&info->client.sockFd);
  993. wolfSSL_free(cli_ssl);
  994. cli_ssl = NULL;
  995. }
  996. exit:
  997. if (ret != 0 && ret != WOLFSSL_SUCCESS) {
  998. fprintf(stderr, "Client Error: %d (%s)\n", ret,
  999. wolfSSL_ERR_reason_error_string(ret));
  1000. }
  1001. /* clean up */
  1002. CloseAndCleanupSocket(&info->client.sockFd);
  1003. if (cli_ssl != NULL)
  1004. wolfSSL_free(cli_ssl);
  1005. if (cli_ctx != NULL)
  1006. wolfSSL_CTX_free(cli_ctx);
  1007. XFREE(readBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1008. XFREE(writeBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1009. info->client.ret = ret;
  1010. return ret;
  1011. }
  1012. #ifdef HAVE_PTHREAD
  1013. static void* client_thread(void* args)
  1014. {
  1015. int ret;
  1016. info_t* info = (info_t*)args;
  1017. ret = bench_tls_client(info);
  1018. pthread_cond_signal(&info->to_server.cond);
  1019. info->to_client.done = 1;
  1020. info->client.ret = ret;
  1021. return NULL;
  1022. }
  1023. #endif /* HAVE_PTHREAD */
  1024. #endif /* !NO_WOLFSSL_CLIENT */
  1025. #ifndef NO_WOLFSSL_SERVER
  1026. static int SetupSocketAndListen(int* listenFd, word32 port, int doDTLS)
  1027. {
  1028. struct sockaddr_in servAddr;
  1029. #if defined(_MSC_VER) || defined(__MINGW32__)
  1030. char optval = 1;
  1031. #else
  1032. int optval = 1;
  1033. #endif
  1034. #ifndef WOLFSSL_DTLS
  1035. (void) doDTLS;
  1036. #endif
  1037. /* Setup server address */
  1038. XMEMSET(&servAddr, 0, sizeof(servAddr));
  1039. servAddr.sin_family = AF_INET;
  1040. servAddr.sin_port = htons(port);
  1041. servAddr.sin_addr.s_addr = INADDR_ANY;
  1042. #ifdef WOLFSSL_DTLS
  1043. if (doDTLS) {
  1044. /* Create a socket that is implemented on the User Datagram Protocol/
  1045. * Interet Protocol(UDP/IP protocol). */
  1046. if((*listenFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
  1047. fprintf(stderr, "ERROR: failed to create the socket\n");
  1048. return -1;
  1049. }
  1050. } else
  1051. #endif
  1052. /* Create a socket that uses an Internet IPv4 address,
  1053. * Sets the socket to be stream based (TCP),
  1054. * 0 means choose the default protocol. */
  1055. if ((*listenFd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
  1056. fprintf(stderr, "ERROR: failed to create the socket\n");
  1057. return -1;
  1058. }
  1059. /* allow reuse */
  1060. if (setsockopt(*listenFd, SOL_SOCKET, SO_REUSEADDR,
  1061. &optval, sizeof(optval)) == -1) {
  1062. fprintf(stderr, "setsockopt SO_REUSEADDR failed\n");
  1063. return -1;
  1064. }
  1065. /* Listen for the client. */
  1066. if (bind(*listenFd, (struct sockaddr*)&servAddr,
  1067. sizeof(servAddr)) == -1) {
  1068. fprintf(stderr, "ERROR: failed to bind\n");
  1069. return -1;
  1070. }
  1071. #ifdef WOLFSSL_DTLS
  1072. if (!doDTLS)
  1073. #endif
  1074. if (listen(*listenFd, 5) != 0) {
  1075. fprintf(stderr, "ERROR: failed to listen\n");
  1076. return -1;
  1077. }
  1078. #ifdef BENCH_USE_NONBLOCK
  1079. if (SetSocketNonBlocking(*listenFd) != 0) {
  1080. return -1;
  1081. }
  1082. #endif
  1083. return 0;
  1084. }
  1085. static int SocketWaitClient(info_t* info)
  1086. {
  1087. int connd;
  1088. struct sockaddr_in clientAddr;
  1089. socklen_t size = sizeof(clientAddr);
  1090. #ifdef WOLFSSL_DTLS
  1091. char msg[64];
  1092. if (info->doDTLS) {
  1093. #ifdef HAVE_PTHREAD
  1094. if (!info->clientOrserverOnly) {
  1095. pthread_mutex_lock(&info->dtls_mutex);
  1096. info->serverReady = 1;
  1097. pthread_cond_signal(&info->dtls_cond);
  1098. pthread_mutex_unlock(&info->dtls_mutex);
  1099. }
  1100. #endif
  1101. connd = (int)recvfrom(info->listenFd, (char *)msg, sizeof(msg),
  1102. MSG_PEEK, (struct sockaddr*)&clientAddr, &size);
  1103. if (connd < -1) {
  1104. fprintf(stderr, "ERROR: failed to accept the connection\n");
  1105. return -1;
  1106. }
  1107. XMEMCPY(&info->clientAddr, &clientAddr, sizeof(clientAddr));
  1108. info->server.sockFd = info->listenFd;
  1109. } else {
  1110. #endif
  1111. #ifdef HAVE_PTHREAD
  1112. info->serverListening = 1;
  1113. #endif
  1114. if ((connd = accept(info->listenFd, (struct sockaddr*)&clientAddr, &size)) == -1) {
  1115. if (errno == SOCKET_EWOULDBLOCK)
  1116. return -2;
  1117. fprintf(stderr, "ERROR: failed to accept the connection\n");
  1118. return -1;
  1119. }
  1120. info->server.sockFd = connd;
  1121. #ifdef WOLFSSL_DTLS
  1122. }
  1123. #endif
  1124. if (info->showVerbose) {
  1125. fprintf(stderr, "Got client %d\n", connd);
  1126. }
  1127. return 0;
  1128. }
  1129. static void CloseAndCleanupListenSocket(int* listenFd)
  1130. {
  1131. if (*listenFd != -1) {
  1132. close(*listenFd);
  1133. *listenFd = -1;
  1134. }
  1135. }
  1136. static int bench_tls_server(info_t* info)
  1137. {
  1138. byte *readBuf = NULL;
  1139. double start;
  1140. int ret, len = 0, readBufSz;
  1141. WOLFSSL_CTX* srv_ctx = NULL;
  1142. WOLFSSL* srv_ssl = NULL;
  1143. int tls13 = XSTRNCMP(info->cipher, "TLS13", 5) == 0;
  1144. int total_sz;
  1145. /* set up server */
  1146. #ifdef WOLFSSL_DTLS
  1147. if(info->doDTLS) {
  1148. if(tls13) return WOLFSSL_SUCCESS;
  1149. srv_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method());
  1150. } else {
  1151. #endif
  1152. #ifdef WOLFSSL_TLS13
  1153. if (tls13)
  1154. srv_ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
  1155. #endif
  1156. if (!tls13)
  1157. srv_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method());
  1158. #ifdef WOLFSSL_DTLS
  1159. }
  1160. #endif
  1161. if (srv_ctx == NULL) {
  1162. fprintf(stderr, "error creating server ctx\n");
  1163. ret = MEMORY_E; goto exit;
  1164. }
  1165. #ifndef NO_CERTS
  1166. #ifdef HAVE_ECC
  1167. if (XSTRSTR(info->cipher, "ECDSA")) {
  1168. ret = wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, ecc_key_der_256,
  1169. sizeof_ecc_key_der_256, WOLFSSL_FILETYPE_ASN1);
  1170. }
  1171. else
  1172. #endif
  1173. {
  1174. ret = wolfSSL_CTX_use_PrivateKey_buffer(srv_ctx, server_key_der_2048,
  1175. sizeof_server_key_der_2048, WOLFSSL_FILETYPE_ASN1);
  1176. }
  1177. if (ret != WOLFSSL_SUCCESS) {
  1178. fprintf(stderr, "error loading server key\n");
  1179. goto exit;
  1180. }
  1181. #ifdef HAVE_ECC
  1182. if (XSTRSTR(info->cipher, "ECDSA")) {
  1183. ret = wolfSSL_CTX_use_certificate_buffer(srv_ctx, serv_ecc_der_256,
  1184. sizeof_serv_ecc_der_256, WOLFSSL_FILETYPE_ASN1);
  1185. }
  1186. else
  1187. #endif
  1188. {
  1189. ret = wolfSSL_CTX_use_certificate_buffer(srv_ctx, server_cert_der_2048,
  1190. sizeof_server_cert_der_2048, WOLFSSL_FILETYPE_ASN1);
  1191. }
  1192. if (ret != WOLFSSL_SUCCESS) {
  1193. fprintf(stderr, "error loading server cert\n");
  1194. goto exit;
  1195. }
  1196. #endif /* !NO_CERTS */
  1197. wolfSSL_CTX_SetIOSend(srv_ctx, ServerSend);
  1198. wolfSSL_CTX_SetIORecv(srv_ctx, ServerRecv);
  1199. /* set cipher suite */
  1200. ret = wolfSSL_CTX_set_cipher_list(srv_ctx, info->cipher);
  1201. if (ret != WOLFSSL_SUCCESS) {
  1202. fprintf(stderr, "error setting cipher suite\n");
  1203. goto exit;
  1204. }
  1205. #ifndef NO_DH
  1206. ret = wolfSSL_CTX_SetMinDhKey_Sz(srv_ctx, MIN_DHKEY_BITS);
  1207. if (ret != WOLFSSL_SUCCESS) {
  1208. fprintf(stderr, "Error setting minimum DH key size\n");
  1209. goto exit;
  1210. }
  1211. #endif
  1212. /* Allocate read buffer */
  1213. readBufSz = info->packetSize;
  1214. readBuf = (unsigned char*)XMALLOC(readBufSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1215. if (readBuf == NULL) {
  1216. fprintf(stderr, "failed to allocate read memory\n");
  1217. ret = MEMORY_E; goto exit;
  1218. }
  1219. /* BENCHMARK CONNECTIONS LOOP */
  1220. while (!info->server.shutdown) {
  1221. #ifdef BENCH_USE_NONBLOCK
  1222. int err;
  1223. #endif
  1224. #ifdef HAVE_PTHREAD
  1225. if (!info->useLocalMem)
  1226. #endif
  1227. {
  1228. /* Accept client connections */
  1229. ret = SocketWaitClient(info);
  1230. #ifdef BENCH_USE_NONBLOCK
  1231. if (ret == -2) {
  1232. XSLEEP_MS(0);
  1233. continue;
  1234. }
  1235. #endif
  1236. if (ret != 0) {
  1237. goto exit;
  1238. }
  1239. }
  1240. srv_ssl = wolfSSL_new(srv_ctx);
  1241. if (srv_ssl == NULL) {
  1242. fprintf(stderr, "error creating server object\n");
  1243. ret = MEMORY_E; goto exit;
  1244. }
  1245. #ifdef WOLFSSL_TLS13
  1246. if (info->group != 0) {
  1247. ret = wolfSSL_UseKeyShare(srv_ssl, info->group);
  1248. if (ret != WOLFSSL_SUCCESS) {
  1249. fprintf(stderr, "error setting server key share.\n");
  1250. goto exit;
  1251. }
  1252. }
  1253. #endif
  1254. #ifdef WOLFSSL_DTLS
  1255. if (info->doDTLS) {
  1256. ret = wolfSSL_dtls_set_peer(srv_ssl, &info->clientAddr,
  1257. sizeof(info->clientAddr));
  1258. if (ret != WOLFSSL_SUCCESS) {
  1259. fprintf(stderr, "error setting dtls peer\n");
  1260. goto exit;
  1261. }
  1262. }
  1263. #endif
  1264. wolfSSL_SetIOReadCtx(srv_ssl, info);
  1265. wolfSSL_SetIOWriteCtx(srv_ssl, info);
  1266. #ifndef NO_DH
  1267. wolfSSL_SetTmpDH(srv_ssl, dhp, sizeof(dhp), dhg, sizeof(dhg));
  1268. #endif
  1269. /* accept TLS connection */
  1270. start = gettime_secs(1);
  1271. #ifndef BENCH_USE_NONBLOCK
  1272. ret = wolfSSL_accept(srv_ssl);
  1273. #else
  1274. do {
  1275. ret = wolfSSL_accept(srv_ssl);
  1276. err = wolfSSL_get_error(srv_ssl, ret);
  1277. }
  1278. while (err == WOLFSSL_ERROR_WANT_READ || err == WOLFSSL_ERROR_WANT_WRITE);
  1279. #endif
  1280. start = gettime_secs(0) - start;
  1281. if (ret != WOLFSSL_SUCCESS) {
  1282. fprintf(stderr, "error on server accept\n");
  1283. ret = wolfSSL_get_error(srv_ssl, ret);
  1284. goto exit;
  1285. }
  1286. info->server_stats.connTime += start;
  1287. info->server_stats.connCount++;
  1288. /* echo loop */
  1289. ret = 0;
  1290. total_sz = 0;
  1291. while (ret == 0 && total_sz < info->maxSize) {
  1292. double rxTime;
  1293. /* read message from client */
  1294. XMEMSET(readBuf, 0, readBufSz);
  1295. start = gettime_secs(1);
  1296. #ifndef BENCH_USE_NONBLOCK
  1297. ret = wolfSSL_read(srv_ssl, readBuf, readBufSz);
  1298. #else
  1299. do {
  1300. ret = wolfSSL_read(srv_ssl, readBuf, readBufSz);
  1301. err = wolfSSL_get_error(srv_ssl, ret);
  1302. }
  1303. while (err == WOLFSSL_ERROR_WANT_READ);
  1304. #endif
  1305. rxTime = gettime_secs(0) - start;
  1306. /* shutdown signals, no more connections for this cipher */
  1307. if (XSTRSTR((const char*)readBuf, kShutdown) != NULL) {
  1308. info->server.shutdown = 1;
  1309. if (info->showVerbose) {
  1310. fprintf(stderr, "Server shutdown done\n");
  1311. }
  1312. ret = 0; /* success */
  1313. break;
  1314. }
  1315. info->server_stats.rxTime += rxTime;
  1316. if (ret < 0) {
  1317. fprintf(stderr, "error on server read\n");
  1318. ret = wolfSSL_get_error(srv_ssl, ret);
  1319. goto exit;
  1320. }
  1321. info->server_stats.rxTotal += ret;
  1322. len = ret;
  1323. total_sz += ret;
  1324. /* write message back to client */
  1325. start = gettime_secs(1);
  1326. #ifndef BENCH_USE_NONBLOCK
  1327. ret = wolfSSL_write(srv_ssl, readBuf, len);
  1328. #else
  1329. do {
  1330. ret = wolfSSL_write(srv_ssl, readBuf, len);
  1331. err = wolfSSL_get_error(srv_ssl, ret);
  1332. }
  1333. while (err == WOLFSSL_ERROR_WANT_WRITE);
  1334. #endif
  1335. info->server_stats.txTime += gettime_secs(0) - start;
  1336. if (ret < 0) {
  1337. fprintf(stderr, "error on server write\n");
  1338. ret = wolfSSL_get_error(srv_ssl, ret);
  1339. goto exit;
  1340. }
  1341. info->server_stats.txTotal += ret;
  1342. ret = 0; /* reset return code */
  1343. }
  1344. CloseAndCleanupSocket(&info->server.sockFd);
  1345. wolfSSL_free(srv_ssl);
  1346. srv_ssl = NULL;
  1347. #ifdef WOLFSSL_DTLS
  1348. if (info->doDTLS) {
  1349. SetupSocketAndListen(&info->listenFd, info->port, info->doDTLS);
  1350. }
  1351. #endif
  1352. }
  1353. exit:
  1354. if (ret != 0 && ret != WOLFSSL_SUCCESS) {
  1355. fprintf(stderr, "Server Error: %d (%s)\n", ret,
  1356. wolfSSL_ERR_reason_error_string(ret));
  1357. }
  1358. /* clean up */
  1359. CloseAndCleanupSocket(&info->server.sockFd);
  1360. if (srv_ssl != NULL)
  1361. wolfSSL_free(srv_ssl);
  1362. if (srv_ctx != NULL)
  1363. wolfSSL_CTX_free(srv_ctx);
  1364. XFREE(readBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1365. info->server.ret = ret;
  1366. return ret;
  1367. }
  1368. #ifdef HAVE_PTHREAD
  1369. static void* server_thread(void* args)
  1370. {
  1371. int ret = 0;
  1372. info_t* info = (info_t*)args;
  1373. if (!info->useLocalMem) {
  1374. /* Setup TLS server listener */
  1375. #ifdef WOLFSSL_DTLS
  1376. ret = SetupSocketAndListen(&info->listenFd, info->port, info->doDTLS);
  1377. #else
  1378. ret = SetupSocketAndListen(&info->listenFd, info->port, 0);
  1379. #endif
  1380. }
  1381. if (ret == 0) {
  1382. ret = bench_tls_server(info);
  1383. if (!info->useLocalMem) {
  1384. CloseAndCleanupListenSocket(&info->listenFd);
  1385. }
  1386. }
  1387. pthread_cond_signal(&info->to_client.cond);
  1388. info->to_server.done = 1;
  1389. info->server.ret = ret;
  1390. return NULL;
  1391. }
  1392. #endif /* HAVE_PTHREAD */
  1393. #endif /* !NO_WOLFSSL_SERVER */
  1394. #ifdef __GNUC__
  1395. #pragma GCC diagnostic push
  1396. #pragma GCC diagnostic ignored "-Wformat-nonliteral"
  1397. #endif
  1398. static void print_stats(stats_t* wcStat, const char* desc, const char* cipher, const char *group, int verbose)
  1399. {
  1400. const char* formatStr;
  1401. if (verbose) {
  1402. formatStr = "wolfSSL %s Benchmark on %s with group %s:\n"
  1403. "\tTotal : %9d bytes\n"
  1404. "\tNum Conns : %9d\n"
  1405. "\tRx Total : %9.3f ms\n"
  1406. "\tTx Total : %9.3f ms\n"
  1407. "\tRx : %9.3f MB/s\n"
  1408. "\tTx : %9.3f MB/s\n"
  1409. "\tConnect : %9.3f ms\n"
  1410. "\tConnect Avg : %9.3f ms\n";
  1411. }
  1412. else {
  1413. formatStr = "%-6s %-33s %-25s %11d %9d %9.3f %9.3f %9.3f %9.3f %17.3f %15.3f\n";
  1414. }
  1415. fprintf(stderr, formatStr,
  1416. desc,
  1417. cipher,
  1418. group,
  1419. wcStat->txTotal + wcStat->rxTotal,
  1420. wcStat->connCount,
  1421. wcStat->rxTime * 1000,
  1422. wcStat->txTime * 1000,
  1423. wcStat->rxTotal / wcStat->rxTime / 1024 / 1024,
  1424. wcStat->txTotal / wcStat->txTime / 1024 / 1024,
  1425. wcStat->connTime * 1000,
  1426. wcStat->connTime * 1000 / wcStat->connCount);
  1427. }
  1428. static void Usage(void)
  1429. {
  1430. fprintf(stderr, "tls_bench " LIBWOLFSSL_VERSION_STRING
  1431. " NOTE: All files relative to wolfSSL home dir\n");
  1432. fprintf(stderr, "-? Help, print this usage\n");
  1433. fprintf(stderr, "-c Run as client only, no threading and uses sockets\n");
  1434. fprintf(stderr, "-s Run as server only, no threading and uses sockets\n");
  1435. fprintf(stderr, "-h Host (default %s)\n", BENCH_DEFAULT_HOST);
  1436. fprintf(stderr, "-P Port (default %d)\n", BENCH_DEFAULT_PORT);
  1437. fprintf(stderr, "-e List Every cipher suite available\n");
  1438. fprintf(stderr, "-i Show peer info\n");
  1439. #ifdef WOLFSSL_TLS13
  1440. fprintf(stderr, "-g Run through each of the TLS 1.3 groups that are available\n");
  1441. #endif
  1442. fprintf(stderr, "-l <str> Cipher suite list (: delimited)\n");
  1443. fprintf(stderr, "-t <num> Time <num> (seconds) to run each test (default %d)\n", BENCH_RUNTIME_SEC);
  1444. fprintf(stderr, "-p <num> The packet size <num> in bytes [1-16kB] (default %d)\n", TEST_PACKET_SIZE);
  1445. #ifdef WOLFSSL_DTLS
  1446. fprintf(stderr, " In the case of DTLS, [1-8kB] (default %d)\n", TEST_DTLS_PACKET_SIZE);
  1447. #endif
  1448. fprintf(stderr, "-S <num> The total size <num> in bytes (default %d)\n", TEST_MAX_SIZE);
  1449. fprintf(stderr, "-v Show verbose output\n");
  1450. #ifdef DEBUG_WOLFSSL
  1451. fprintf(stderr, "-d Enable debug messages\n");
  1452. #endif
  1453. #ifdef HAVE_PTHREAD
  1454. fprintf(stderr, "-T <num> Number of threaded server/client pairs (default %d)\n", NUM_THREAD_PAIRS);
  1455. fprintf(stderr, "-m Use local memory, not socket\n");
  1456. #endif
  1457. #ifdef WOLFSSL_DTLS
  1458. fprintf(stderr, "-u Use DTLS\n");
  1459. #endif
  1460. }
  1461. static void ShowCiphers(void)
  1462. {
  1463. char ciphers[WOLFSSL_CIPHER_LIST_MAX_SIZE];
  1464. int ret = wolfSSL_get_ciphers(ciphers, (int)sizeof(ciphers));
  1465. if (ret == WOLFSSL_SUCCESS)
  1466. fprintf(stderr, "%s\n", ciphers);
  1467. }
  1468. #ifdef WOLFSSL_TLS13
  1469. static int SetupSupportedGroups(int verbose)
  1470. {
  1471. int i;
  1472. WOLFSSL_CTX* ctx = NULL;
  1473. WOLFSSL* ssl = NULL;
  1474. int ret = 0;
  1475. if (ret == 0) {
  1476. #ifdef NO_WOLFSSL_CLIENT
  1477. ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method());
  1478. #else
  1479. ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method());
  1480. #endif
  1481. if (ctx == NULL) {
  1482. ret = -1;
  1483. }
  1484. }
  1485. if (ret == 0) {
  1486. ssl = wolfSSL_new(ctx);
  1487. if (ssl == NULL) {
  1488. ret = -1;
  1489. }
  1490. }
  1491. /* Determine which groups are actually supported. */
  1492. for (i = 0; groups[i].name != NULL; i++) {
  1493. if (ret == 0) {
  1494. int uks_ret = wolfSSL_UseKeyShare(ssl, groups[i].group);
  1495. if (uks_ret == WOLFSSL_SUCCESS) {
  1496. if (verbose) {
  1497. printf("Will benchmark the following group: %s\n",
  1498. groups[i].name);
  1499. }
  1500. } else if (uks_ret == BAD_FUNC_ARG || uks_ret == NOT_COMPILED_IN) {
  1501. groups[i].group = 0;
  1502. if (verbose) {
  1503. printf("Will NOT benchmark the following group: %s\n",
  1504. groups[i].name);
  1505. }
  1506. } else {
  1507. ret = -1;
  1508. }
  1509. }
  1510. }
  1511. if (ssl != NULL)
  1512. wolfSSL_free(ssl);
  1513. if (ctx != NULL)
  1514. wolfSSL_CTX_free(ctx);
  1515. return ret;
  1516. }
  1517. #endif
  1518. #ifdef __GNUC__
  1519. #pragma GCC diagnostic pop
  1520. #endif
  1521. int bench_tls(void* args)
  1522. {
  1523. int ret = 0;
  1524. info_t *theadInfo = NULL, *info;
  1525. stats_t cli_comb, srv_comb;
  1526. int i;
  1527. #ifdef WOLFSSL_TLS13
  1528. int group_index = 0;
  1529. #endif
  1530. char *cipher, *next_cipher, *ciphers = NULL;
  1531. int argc = 0;
  1532. char** argv = NULL;
  1533. int ch;
  1534. /* Vars configured by command line arguments */
  1535. int argRuntimeSec = BENCH_RUNTIME_SEC;
  1536. char *argCipherList = NULL;
  1537. int argTestPacketSize = TEST_PACKET_SIZE;
  1538. int argTestMaxSize = TEST_MAX_SIZE;
  1539. int argThreadPairs = NUM_THREAD_PAIRS;
  1540. int argShowVerbose = SHOW_VERBOSE;
  1541. int argClientOnly = 0;
  1542. int argServerOnly = 0;
  1543. const char* argHost = BENCH_DEFAULT_HOST;
  1544. int argPort = BENCH_DEFAULT_PORT;
  1545. int argShowPeerInfo = 0;
  1546. #ifdef HAVE_PTHREAD
  1547. int doShutdown;
  1548. #endif
  1549. #if !defined(NO_WOLFSSL_SERVER) || defined(HAVE_PTHREAD)
  1550. int argLocalMem = 0;
  1551. int listenFd = -1;
  1552. #endif
  1553. #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
  1554. int option_p = 0;
  1555. #endif
  1556. #ifdef WOLFSSL_DTLS
  1557. int doDTLS = 0;
  1558. #endif
  1559. #ifdef WOLFSSL_TLS13
  1560. int argDoGroups = 0;
  1561. #endif
  1562. if (args != NULL) {
  1563. argc = ((func_args*)args)->argc;
  1564. argv = ((func_args*)args)->argv;
  1565. ((func_args*)args)->return_code = -1; /* error state */
  1566. }
  1567. /* Initialize wolfSSL */
  1568. wolfSSL_Init();
  1569. #ifdef WC_RNG_SEED_CB
  1570. wc_SetSeed_Cb(wc_GenerateSeed);
  1571. #endif
  1572. /* Parse command line arguments */
  1573. while ((ch = mygetopt(argc, argv, "?" "udeil:p:t:vT:sch:P:mS:g")) != -1) {
  1574. switch (ch) {
  1575. case '?' :
  1576. Usage();
  1577. goto exit;
  1578. case 's':
  1579. argServerOnly = 1;
  1580. break;
  1581. case 'c':
  1582. argClientOnly = 1;
  1583. break;
  1584. case 'h':
  1585. argHost = myoptarg;
  1586. break;
  1587. case 'P':
  1588. argPort = atoi(myoptarg);
  1589. break;
  1590. case 'd' :
  1591. #ifdef DEBUG_WOLFSSL
  1592. wolfSSL_Debugging_ON();
  1593. #endif
  1594. break;
  1595. case 'e' :
  1596. ShowCiphers();
  1597. goto exit;
  1598. case 'g' :
  1599. #ifdef WOLFSSL_TLS13
  1600. argDoGroups = 1;
  1601. break;
  1602. #else
  1603. fprintf(stderr, "There are only groups in TLS 1.3\n");
  1604. Usage();
  1605. ret = MY_EX_USAGE; goto exit;
  1606. #endif
  1607. case 'i' :
  1608. argShowPeerInfo = 1;
  1609. break;
  1610. case 'l' :
  1611. argCipherList = myoptarg;
  1612. break;
  1613. case 'p' :
  1614. argTestPacketSize = atoi(myoptarg);
  1615. if (argTestPacketSize > (16 * 1024)) {
  1616. fprintf(stderr, "Invalid packet size %d\n", argTestPacketSize);
  1617. Usage();
  1618. ret = MY_EX_USAGE; goto exit;
  1619. }
  1620. #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
  1621. option_p = 1;
  1622. #endif
  1623. break;
  1624. case 'S' :
  1625. argTestMaxSize = atoi(myoptarg);
  1626. break;
  1627. case 't' :
  1628. argRuntimeSec = atoi(myoptarg);
  1629. break;
  1630. case 'v' :
  1631. argShowVerbose = 1;
  1632. break;
  1633. case 'T' :
  1634. #ifdef HAVE_PTHREAD
  1635. argThreadPairs = atoi(myoptarg);
  1636. #endif
  1637. break;
  1638. case 'm':
  1639. #ifdef HAVE_PTHREAD
  1640. argLocalMem = 1;
  1641. #endif
  1642. break;
  1643. case 'u':
  1644. #ifdef WOLFSSL_DTLS
  1645. doDTLS = 1;
  1646. #ifdef BENCH_USE_NONBLOCK
  1647. fprintf(stderr, "tls_bench hasn't yet supported DTLS "
  1648. "non-blocking mode.\n");
  1649. Usage();
  1650. ret = MY_EX_USAGE; goto exit;
  1651. #endif
  1652. #endif
  1653. break;
  1654. default:
  1655. Usage();
  1656. ret = MY_EX_USAGE; goto exit;
  1657. }
  1658. }
  1659. /* reset for test cases */
  1660. myoptind = 0;
  1661. if (argCipherList != NULL) {
  1662. /* Use the list from CL argument */
  1663. cipher = argCipherList;
  1664. }
  1665. else {
  1666. /* Run for each cipher */
  1667. ciphers = (char*)XMALLOC(WOLFSSL_CIPHER_LIST_MAX_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1668. if (ciphers == NULL) {
  1669. goto exit;
  1670. }
  1671. wolfSSL_get_ciphers(ciphers, WOLFSSL_CIPHER_LIST_MAX_SIZE);
  1672. cipher = ciphers;
  1673. }
  1674. #ifdef WOLFSSL_TLS13
  1675. if (argDoGroups) {
  1676. if (SetupSupportedGroups(argShowVerbose) != 0) {
  1677. goto exit;
  1678. }
  1679. }
  1680. #endif
  1681. /* for server or client side only, only 1 thread is allowed */
  1682. if (argServerOnly || argClientOnly) {
  1683. argThreadPairs = 1;
  1684. }
  1685. #ifndef HAVE_PTHREAD
  1686. else {
  1687. fprintf(stderr, "Threading is not enabled, so please use -s or -c to indicate side\n");
  1688. Usage();
  1689. ret = MY_EX_USAGE; goto exit;
  1690. }
  1691. #endif
  1692. /* Allocate test info array */
  1693. theadInfo = (info_t*)XMALLOC(sizeof(info_t) * argThreadPairs, NULL,
  1694. DYNAMIC_TYPE_TMP_BUFFER);
  1695. if (theadInfo == NULL) {
  1696. ret = MEMORY_E; goto exit;
  1697. }
  1698. XMEMSET(theadInfo, 0, sizeof(info_t) * argThreadPairs);
  1699. #ifndef NO_WOLFSSL_SERVER
  1700. /* Use same listen socket to avoid timing issues between client and server */
  1701. if (argServerOnly && !argLocalMem) {
  1702. /* Setup TLS server listener */
  1703. #ifdef WOLFSSL_DTLS
  1704. ret = SetupSocketAndListen(&listenFd, argPort, doDTLS);
  1705. #else
  1706. ret = SetupSocketAndListen(&listenFd, argPort, 0);
  1707. #endif
  1708. if (ret != 0) goto exit;
  1709. }
  1710. #endif
  1711. #if defined(WOLFSSL_DTLS) && !defined(NO_WOLFSSL_SERVER)
  1712. if (doDTLS) {
  1713. if (argLocalMem) {
  1714. fprintf(stderr, "tls_bench hasn't yet supported DTLS with local memory.\n");
  1715. ret = MY_EX_USAGE; goto exit;
  1716. }
  1717. if (option_p && argTestPacketSize > TEST_DTLS_PACKET_SIZE){
  1718. fprintf(stderr, "Invalid packet size %d\n", argTestPacketSize);
  1719. Usage();
  1720. ret = MY_EX_USAGE; goto exit;
  1721. } else {
  1722. /* argTestPacketSize would be default for tcp packet */
  1723. if (argTestPacketSize >= TEST_PACKET_SIZE)
  1724. argTestPacketSize = TEST_DTLS_PACKET_SIZE;
  1725. }
  1726. }
  1727. #endif
  1728. fprintf(stderr, "Running TLS Benchmarks...\n");
  1729. /* parse by : */
  1730. while ((cipher != NULL) && (cipher[0] != '\0')) {
  1731. const char *gname = "N/A";
  1732. next_cipher = strchr(cipher, ':');
  1733. if (next_cipher != NULL) {
  1734. cipher[next_cipher - cipher] = '\0';
  1735. }
  1736. if (argShowVerbose) {
  1737. fprintf(stderr, "Cipher: %s\n", cipher);
  1738. }
  1739. #ifdef WOLFSSL_TLS13
  1740. for (group_index = 0; groups[group_index].name != NULL; group_index++) {
  1741. gname = theadInfo[0].group == 0 ? "N/A" : groups[group_index].name;
  1742. if (argDoGroups && groups[group_index].group == 0) {
  1743. /* Skip unsupported group. */
  1744. continue;
  1745. }
  1746. #endif
  1747. for (i=0; i<argThreadPairs; i++) {
  1748. info = &theadInfo[i];
  1749. XMEMSET(info, 0, sizeof(info_t));
  1750. info->host = argHost;
  1751. info->port = argPort + i; /* threads must have separate ports */
  1752. info->cipher = cipher;
  1753. #ifdef WOLFSSL_TLS13
  1754. if (argDoGroups && XSTRNCMP(theadInfo[0].cipher, "TLS13", 5) == 0)
  1755. info->group = groups[group_index].group;
  1756. else
  1757. #endif
  1758. info->group = 0;
  1759. info->packetSize = argTestPacketSize;
  1760. info->runTimeSec = argRuntimeSec;
  1761. info->maxSize = argTestMaxSize;
  1762. info->showPeerInfo = argShowPeerInfo;
  1763. info->showVerbose = argShowVerbose;
  1764. #ifndef NO_WOLFSSL_SERVER
  1765. info->listenFd = listenFd;
  1766. #endif
  1767. info->client.sockFd = -1;
  1768. info->server.sockFd = -1;
  1769. #ifdef WOLFSSL_DTLS
  1770. info->doDTLS = doDTLS;
  1771. #ifdef HAVE_PTHREAD
  1772. info->serverReady = 0;
  1773. if (argServerOnly || argClientOnly) {
  1774. info->clientOrserverOnly = 1;
  1775. }
  1776. #endif
  1777. #endif
  1778. if (argClientOnly) {
  1779. #ifndef NO_WOLFSSL_CLIENT
  1780. ret = bench_tls_client(info);
  1781. #endif
  1782. }
  1783. else if (argServerOnly) {
  1784. #ifndef NO_WOLFSSL_SERVER
  1785. ret = bench_tls_server(info);
  1786. #endif
  1787. }
  1788. else {
  1789. #ifdef HAVE_PTHREAD
  1790. info->useLocalMem = argLocalMem;
  1791. pthread_mutex_init(&info->to_server.mutex, NULL);
  1792. pthread_mutex_init(&info->to_client.mutex, NULL);
  1793. #ifdef WOLFSSL_DTLS
  1794. pthread_mutex_init(&info->dtls_mutex, NULL);
  1795. pthread_cond_init(&info->dtls_cond, NULL);
  1796. #endif
  1797. pthread_cond_init(&info->to_server.cond, NULL);
  1798. pthread_cond_init(&info->to_client.cond, NULL);
  1799. pthread_create(&info->to_server.tid, NULL, server_thread,
  1800. info);
  1801. pthread_create(&info->to_client.tid, NULL, client_thread,
  1802. info);
  1803. /* State that we won't be joining this thread */
  1804. pthread_detach(info->to_server.tid);
  1805. pthread_detach(info->to_client.tid);
  1806. #endif
  1807. }
  1808. }
  1809. #ifdef HAVE_PTHREAD
  1810. /* For threading, wait for completion */
  1811. if (!argClientOnly && !argServerOnly) {
  1812. /* Wait until threads are marked done */
  1813. do {
  1814. doShutdown = 1;
  1815. for (i = 0; i < argThreadPairs; ++i) {
  1816. info = &theadInfo[i];
  1817. if (!info->to_client.done || !info->to_server.done) {
  1818. doShutdown = 0;
  1819. XSLEEP_MS(1000); /* Allow other threads to run */
  1820. }
  1821. }
  1822. } while (!doShutdown);
  1823. if (argShowVerbose) {
  1824. fprintf(stderr, "Shutdown complete\n");
  1825. }
  1826. }
  1827. #endif /* HAVE_PTHREAD */
  1828. if (argShowVerbose) {
  1829. /* print results */
  1830. for (i = 0; i < argThreadPairs; ++i) {
  1831. info = &theadInfo[i];
  1832. fprintf(stderr, "\nThread %d\n", i);
  1833. #ifndef NO_WOLFSSL_SERVER
  1834. if (!argClientOnly)
  1835. print_stats(&info->server_stats, "Server", info->cipher, gname, 1);
  1836. #endif
  1837. #ifndef NO_WOLFSSL_CLIENT
  1838. if (!argServerOnly)
  1839. print_stats(&info->client_stats, "Client", info->cipher, gname, 1);
  1840. #endif
  1841. }
  1842. }
  1843. /* print combined results for more than one thread */
  1844. XMEMSET(&cli_comb, 0, sizeof(cli_comb));
  1845. XMEMSET(&srv_comb, 0, sizeof(srv_comb));
  1846. for (i = 0; i < argThreadPairs; ++i) {
  1847. info = &theadInfo[i];
  1848. cli_comb.connCount += info->client_stats.connCount;
  1849. srv_comb.connCount += info->server_stats.connCount;
  1850. cli_comb.connTime += info->client_stats.connTime;
  1851. srv_comb.connTime += info->server_stats.connTime;
  1852. cli_comb.rxTotal += info->client_stats.rxTotal;
  1853. srv_comb.rxTotal += info->server_stats.rxTotal;
  1854. cli_comb.rxTime += info->client_stats.rxTime;
  1855. srv_comb.rxTime += info->server_stats.rxTime;
  1856. cli_comb.txTotal += info->client_stats.txTotal;
  1857. srv_comb.txTotal += info->server_stats.txTotal;
  1858. cli_comb.txTime += info->client_stats.txTime;
  1859. srv_comb.txTime += info->server_stats.txTime;
  1860. }
  1861. if (argShowVerbose) {
  1862. fprintf(stderr, "Totals for %d Threads\n", argThreadPairs);
  1863. }
  1864. else {
  1865. fprintf(stderr, "%-6s %-33s %-25s %11s %9s %9s %9s %9s %9s %17s %15s\n",
  1866. "Side", "Cipher", "Group", "Total Bytes", "Num Conns", "Rx ms", "Tx ms",
  1867. "Rx MB/s", "Tx MB/s", "Connect Total ms", "Connect Avg ms");
  1868. #ifndef NO_WOLFSSL_SERVER
  1869. if (!argClientOnly)
  1870. print_stats(&srv_comb, "Server", theadInfo[0].cipher, gname, 0);
  1871. #endif
  1872. #ifndef NO_WOLFSSL_CLIENT
  1873. if (!argServerOnly)
  1874. print_stats(&cli_comb, "Client", theadInfo[0].cipher, gname, 0);
  1875. #endif
  1876. }
  1877. #ifdef WOLFSSL_TLS13
  1878. if (!argDoGroups || theadInfo[0].group == 0) {
  1879. /* We only needed to do this once because they don't want to
  1880. * benchmarks groups or this isn't a TLS 1.3 cipher. */
  1881. break;
  1882. }
  1883. }
  1884. #endif
  1885. /* target next cipher */
  1886. cipher = (next_cipher != NULL) ? (next_cipher + 1) : NULL;
  1887. } /* while */
  1888. exit:
  1889. #ifndef NO_WOLFSSL_SERVER
  1890. if (argServerOnly && !argLocalMem) {
  1891. /* Close server listener */
  1892. CloseAndCleanupListenSocket(&listenFd);
  1893. }
  1894. #endif
  1895. /* Cleanup the wolfSSL environment */
  1896. wolfSSL_Cleanup();
  1897. /* Free theadInfo array */
  1898. XFREE(theadInfo, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1899. /* Free cipher list */
  1900. XFREE(ciphers, NULL, DYNAMIC_TYPE_TMP_BUFFER);
  1901. /* Return reporting a success */
  1902. if (args)
  1903. ((func_args*)args)->return_code = ret;
  1904. return ret;
  1905. }
  1906. #endif /* (!NO_WOLFSSL_CLIENT || !NO_WOLFSSL_SERVER) && !WOLFCRYPT_ONLY && USE_WOLFSSL_IO */
  1907. #ifndef NO_MAIN_DRIVER
  1908. int main(int argc, char** argv)
  1909. {
  1910. func_args args;
  1911. args.argc = argc;
  1912. args.argv = argv;
  1913. args.return_code = 0;
  1914. #if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \
  1915. !defined(WOLFCRYPT_ONLY) && defined(USE_WOLFSSL_IO)
  1916. bench_tls(&args);
  1917. #endif
  1918. return args.return_code;
  1919. }
  1920. #endif /* !NO_MAIN_DRIVER */