tls_bench.c 72 KB

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