socket.c 70 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /***********************************************************************
  6. **
  7. ** Name: socket.c
  8. **
  9. ** Description: Test socket functionality.
  10. **
  11. ** Modification History:
  12. */
  13. #include "primpl.h"
  14. #include "plgetopt.h"
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <errno.h>
  18. #ifdef XP_UNIX
  19. #include <sys/mman.h>
  20. #endif
  21. #if defined(_PR_PTHREADS)
  22. #include <pthread.h>
  23. #endif
  24. #ifdef WIN32
  25. #include <process.h>
  26. #endif
  27. static int _debug_on = 0;
  28. static int test_cancelio = 0;
  29. #include "obsolete/prsem.h"
  30. #ifdef XP_PC
  31. #define mode_t int
  32. #endif
  33. #define DPRINTF(arg) if (_debug_on) printf arg
  34. #ifdef XP_PC
  35. char *TEST_DIR = "prdir";
  36. char *SMALL_FILE_NAME = "prsmallf";
  37. char *LARGE_FILE_NAME = "prlargef";
  38. #else
  39. char *TEST_DIR = "./tmp-prsocket_test_dir";
  40. char *SMALL_FILE_NAME = "./tmp-prsocket_test_dir/small_file";
  41. char *LARGE_FILE_NAME = "./tmp-prsocket_test_dir/large_file";
  42. #endif
  43. #define SMALL_FILE_SIZE (3 * 1024) /* 3 KB */
  44. #define SMALL_FILE_OFFSET_1 (512)
  45. #define SMALL_FILE_LEN_1 (1 * 1024) /* 1 KB */
  46. #define SMALL_FILE_OFFSET_2 (75)
  47. #define SMALL_FILE_LEN_2 (758)
  48. #define SMALL_FILE_OFFSET_3 (1024)
  49. #define SMALL_FILE_LEN_3 (SMALL_FILE_SIZE - SMALL_FILE_OFFSET_3)
  50. #define SMALL_FILE_HEADER_SIZE (64) /* 64 bytes */
  51. #define SMALL_FILE_TRAILER_SIZE (128) /* 128 bytes */
  52. #define LARGE_FILE_SIZE (3 * 1024 * 1024) /* 3 MB */
  53. #define LARGE_FILE_OFFSET_1 (0)
  54. #define LARGE_FILE_LEN_1 (2 * 1024 * 1024) /* 2 MB */
  55. #define LARGE_FILE_OFFSET_2 (64)
  56. #define LARGE_FILE_LEN_2 (1 * 1024 * 1024 + 75)
  57. #define LARGE_FILE_OFFSET_3 (2 * 1024 * 1024 - 128)
  58. #define LARGE_FILE_LEN_3 (LARGE_FILE_SIZE - LARGE_FILE_OFFSET_3)
  59. #define LARGE_FILE_OFFSET_4 PR_GetPageSize()
  60. #define LARGE_FILE_LEN_4 769
  61. #define LARGE_FILE_HEADER_SIZE (512)
  62. #define LARGE_FILE_TRAILER_SIZE (64)
  63. #define BUF_DATA_SIZE (2 * 1024)
  64. #define TCP_MESG_SIZE 1024
  65. /*
  66. * set UDP datagram size small enough that datagrams sent to a port on the
  67. * local host will not be lost
  68. */
  69. #define UDP_DGRAM_SIZE 128
  70. #define NUM_TCP_CLIENTS 5 /* for a listen queue depth of 5 */
  71. #define NUM_UDP_CLIENTS 10
  72. #define NUM_TRANSMITFILE_CLIENTS 4
  73. #define NUM_TCP_CONNECTIONS_PER_CLIENT 5
  74. #define NUM_TCP_MESGS_PER_CONNECTION 10
  75. #define NUM_UDP_DATAGRAMS_PER_CLIENT 5
  76. #define TCP_SERVER_PORT 10000
  77. #define UDP_SERVER_PORT TCP_SERVER_PORT
  78. #define SERVER_MAX_BIND_COUNT 100
  79. #ifdef WINCE
  80. #define perror(s)
  81. #endif
  82. static PRInt32 num_tcp_clients = NUM_TCP_CLIENTS;
  83. static PRInt32 num_udp_clients = NUM_UDP_CLIENTS;
  84. static PRInt32 num_transmitfile_clients = NUM_TRANSMITFILE_CLIENTS;
  85. static PRInt32 num_tcp_connections_per_client = NUM_TCP_CONNECTIONS_PER_CLIENT;
  86. static PRInt32 tcp_mesg_size = TCP_MESG_SIZE;
  87. static PRInt32 num_tcp_mesgs_per_connection = NUM_TCP_MESGS_PER_CONNECTION;
  88. static PRInt32 num_udp_datagrams_per_client = NUM_UDP_DATAGRAMS_PER_CLIENT;
  89. static PRInt32 udp_datagram_size = UDP_DGRAM_SIZE;
  90. static PRInt32 thread_count;
  91. PRUint16 server_domain = PR_AF_INET, client_domain = PR_AF_INET;
  92. /* an I/O layer that uses the emulated senfile method */
  93. static PRDescIdentity emuSendFileIdentity;
  94. static PRIOMethods emuSendFileMethods;
  95. int failed_already=0;
  96. typedef struct buffer {
  97. char data[BUF_DATA_SIZE];
  98. } buffer;
  99. PRNetAddr tcp_server_addr, udp_server_addr;
  100. typedef struct Serve_Client_Param {
  101. PRFileDesc *sockfd; /* socket to read from/write to */
  102. PRInt32 datalen; /* bytes of data transfered in each read/write */
  103. } Serve_Client_Param;
  104. typedef struct Server_Param {
  105. PRSemaphore *addr_sem; /* sem to post on, after setting up the address */
  106. PRMonitor *exit_mon; /* monitor to signal on exit */
  107. PRInt32 *exit_counter; /* counter to decrement, before exit */
  108. PRInt32 datalen; /* bytes of data transfered in each read/write */
  109. } Server_Param;
  110. typedef struct Client_Param {
  111. PRNetAddr server_addr;
  112. PRMonitor *exit_mon; /* monitor to signal on exit */
  113. PRInt32 *exit_counter; /* counter to decrement, before exit */
  114. PRInt32 datalen;
  115. PRInt32 udp_connect; /* if set clients connect udp sockets */
  116. } Client_Param;
  117. /* the sendfile method in emuSendFileMethods */
  118. static PRInt32 PR_CALLBACK
  119. emu_SendFile(PRFileDesc *sd, PRSendFileData *sfd,
  120. PRTransmitFileFlags flags, PRIntervalTime timeout)
  121. {
  122. return PR_EmulateSendFile(sd, sfd, flags, timeout);
  123. }
  124. /* the transmitfile method in emuSendFileMethods */
  125. static PRInt32 PR_CALLBACK
  126. emu_TransmitFile(PRFileDesc *sd, PRFileDesc *fd, const void *headers,
  127. PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime timeout)
  128. {
  129. PRSendFileData sfd;
  130. sfd.fd = fd;
  131. sfd.file_offset = 0;
  132. sfd.file_nbytes = 0;
  133. sfd.header = headers;
  134. sfd.hlen = hlen;
  135. sfd.trailer = NULL;
  136. sfd.tlen = 0;
  137. return emu_SendFile(sd, &sfd, flags, timeout);
  138. }
  139. /*
  140. * readn
  141. * read data from sockfd into buf
  142. */
  143. static PRInt32
  144. readn(PRFileDesc *sockfd, char *buf, int len)
  145. {
  146. int rem;
  147. int bytes;
  148. int offset = 0;
  149. int err;
  150. PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
  151. if (test_cancelio) {
  152. timeout = PR_SecondsToInterval(2);
  153. }
  154. for (rem=len; rem; offset += bytes, rem -= bytes) {
  155. DPRINTF(("thread = 0x%lx: calling PR_Recv, bytes = %d\n",
  156. PR_GetCurrentThread(), rem));
  157. retry:
  158. bytes = PR_Recv(sockfd, buf + offset, rem, 0,
  159. timeout);
  160. DPRINTF(("thread = 0x%lx: returning from PR_Recv, bytes = %d\n",
  161. PR_GetCurrentThread(), bytes));
  162. if (bytes < 0) {
  163. #ifdef WINNT
  164. printf("PR_Recv: error = %d oserr = %d\n",(err = PR_GetError()),
  165. PR_GetOSError());
  166. if ((test_cancelio) && (err == PR_IO_TIMEOUT_ERROR)) {
  167. if (PR_NT_CancelIo(sockfd) != PR_SUCCESS) {
  168. printf("PR_NT_CancelIO: error = %d\n",PR_GetError());
  169. }
  170. timeout = PR_INTERVAL_NO_TIMEOUT;
  171. goto retry;
  172. }
  173. #endif
  174. return -1;
  175. }
  176. }
  177. return len;
  178. }
  179. /*
  180. * writen
  181. * write data from buf to sockfd
  182. */
  183. static PRInt32
  184. writen(PRFileDesc *sockfd, char *buf, int len)
  185. {
  186. int rem;
  187. int bytes;
  188. int offset = 0;
  189. for (rem=len; rem; offset += bytes, rem -= bytes) {
  190. DPRINTF(("thread = 0x%lx: calling PR_Send, bytes = %d\n",
  191. PR_GetCurrentThread(), rem));
  192. bytes = PR_Send(sockfd, buf + offset, rem, 0,
  193. PR_INTERVAL_NO_TIMEOUT);
  194. DPRINTF(("thread = 0x%lx: returning from PR_Send, bytes = %d\n",
  195. PR_GetCurrentThread(), bytes));
  196. if (bytes <= 0) {
  197. return -1;
  198. }
  199. }
  200. return len;
  201. }
  202. /*
  203. * Serve_Client
  204. * Thread, started by the server, for serving a client connection.
  205. * Reads data from socket and writes it back, unmodified, and
  206. * closes the socket
  207. */
  208. static void PR_CALLBACK
  209. Serve_Client(void *arg)
  210. {
  211. Serve_Client_Param *scp = (Serve_Client_Param *) arg;
  212. PRFileDesc *sockfd;
  213. buffer *in_buf;
  214. PRInt32 bytes, j;
  215. sockfd = scp->sockfd;
  216. bytes = scp->datalen;
  217. in_buf = PR_NEW(buffer);
  218. if (in_buf == NULL) {
  219. fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
  220. failed_already=1;
  221. goto exit;
  222. }
  223. for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
  224. /*
  225. * Read data from client and send it back to the client unmodified
  226. */
  227. if (readn(sockfd, in_buf->data, bytes) < bytes) {
  228. fprintf(stderr,"prsocket_test: ERROR - Serve_Client:readn\n");
  229. failed_already=1;
  230. goto exit;
  231. }
  232. /* Shutdown only RCV will cause error on Symbian OS */
  233. /*
  234. * shutdown reads, after the last read
  235. */
  236. if (j == num_tcp_mesgs_per_connection - 1)
  237. if (PR_Shutdown(sockfd, PR_SHUTDOWN_RCV) < 0) {
  238. fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
  239. }
  240. DPRINTF(("Serve_Client [0x%lx]: inbuf[0] = 0x%lx\n",PR_GetCurrentThread(),
  241. (*((int *) in_buf->data))));
  242. if (writen(sockfd, in_buf->data, bytes) < bytes) {
  243. fprintf(stderr,"prsocket_test: ERROR - Serve_Client:writen\n");
  244. failed_already=1;
  245. goto exit;
  246. }
  247. }
  248. /*
  249. * shutdown reads and writes
  250. */
  251. if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
  252. fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
  253. failed_already=1;
  254. }
  255. exit:
  256. PR_Close(sockfd);
  257. if (in_buf) {
  258. PR_DELETE(in_buf);
  259. }
  260. }
  261. PRThread* create_new_thread(PRThreadType type,
  262. void (*start)(void *arg),
  263. void *arg,
  264. PRThreadPriority priority,
  265. PRThreadScope scope,
  266. PRThreadState state,
  267. PRUint32 stackSize, PRInt32 index)
  268. {
  269. PRInt32 native_thread = 0;
  270. PR_ASSERT(state == PR_UNJOINABLE_THREAD);
  271. #if defined(_PR_PTHREADS) || defined(WIN32)
  272. switch(index % 4) {
  273. case 0:
  274. scope = (PR_LOCAL_THREAD);
  275. break;
  276. case 1:
  277. scope = (PR_GLOBAL_THREAD);
  278. break;
  279. case 2:
  280. scope = (PR_GLOBAL_BOUND_THREAD);
  281. break;
  282. case 3:
  283. native_thread = 1;
  284. break;
  285. default:
  286. PR_NOT_REACHED("Invalid scope");
  287. break;
  288. }
  289. if (native_thread) {
  290. #if defined(_PR_PTHREADS)
  291. pthread_t tid;
  292. if (!pthread_create(&tid, NULL, (void * (*)(void *)) start, arg)) {
  293. return((PRThread *) tid);
  294. }
  295. else {
  296. return (NULL);
  297. }
  298. #else
  299. HANDLE thandle;
  300. unsigned tid;
  301. thandle = (HANDLE) _beginthreadex(
  302. NULL,
  303. stackSize,
  304. (unsigned (__stdcall *)(void *))start,
  305. arg,
  306. STACK_SIZE_PARAM_IS_A_RESERVATION,
  307. &tid);
  308. return((PRThread *) thandle);
  309. #endif
  310. } else {
  311. return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
  312. }
  313. #else
  314. return(PR_CreateThread(type,start,arg,priority,scope,state,stackSize));
  315. #endif
  316. }
  317. /*
  318. * TCP Server
  319. * Server Thread
  320. * Bind an address to a socket and listen for incoming connections
  321. * Start a Serve_Client thread for each incoming connection.
  322. */
  323. static void PR_CALLBACK
  324. TCP_Server(void *arg)
  325. {
  326. PRThread *t;
  327. Server_Param *sp = (Server_Param *) arg;
  328. Serve_Client_Param *scp;
  329. PRFileDesc *sockfd, *newsockfd;
  330. PRNetAddr netaddr;
  331. PRInt32 i;
  332. /*
  333. * Create a tcp socket
  334. */
  335. if ((sockfd = PR_OpenTCPSocket(server_domain)) == NULL) {
  336. fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
  337. goto exit;
  338. }
  339. memset(&netaddr, 0, sizeof(netaddr));
  340. if (PR_SetNetAddr(PR_IpAddrAny, server_domain, TCP_SERVER_PORT,
  341. &netaddr) == PR_FAILURE) {
  342. fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
  343. goto exit;
  344. }
  345. /*
  346. * try a few times to bind server's address, if addresses are in
  347. * use
  348. */
  349. i = 0;
  350. while (PR_Bind(sockfd, &netaddr) < 0) {
  351. if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
  352. netaddr.inet.port += 2;
  353. if (i++ < SERVER_MAX_BIND_COUNT) {
  354. continue;
  355. }
  356. }
  357. fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
  358. perror("PR_Bind");
  359. failed_already=1;
  360. goto exit;
  361. }
  362. if (PR_Listen(sockfd, 32) < 0) {
  363. fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
  364. failed_already=1;
  365. goto exit;
  366. }
  367. if (PR_GetSockName(sockfd, &netaddr) < 0) {
  368. fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
  369. failed_already=1;
  370. goto exit;
  371. }
  372. DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
  373. netaddr.inet.ip, netaddr.inet.port));
  374. if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
  375. PR_ntohs(PR_NetAddrInetPort(&netaddr)),
  376. &tcp_server_addr) == PR_FAILURE) {
  377. fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
  378. goto exit;
  379. }
  380. if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET))
  381. PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK),
  382. &tcp_server_addr.ipv6.ip);
  383. /*
  384. * Wake up parent thread because server address is bound and made
  385. * available in the global variable 'tcp_server_addr'
  386. */
  387. PR_PostSem(sp->addr_sem);
  388. for (i = 0; i < (num_tcp_clients * num_tcp_connections_per_client); i++) {
  389. /* test both null and non-null 'addr' argument to PR_Accept */
  390. PRNetAddr *addrp = (i%2 ? &netaddr: NULL);
  391. DPRINTF(("TCP_Server: Accepting connection\n"));
  392. if ((newsockfd = PR_Accept(sockfd, addrp,
  393. PR_INTERVAL_NO_TIMEOUT)) == NULL) {
  394. fprintf(stderr,"prsocket_test: ERROR - PR_Accept failed\n");
  395. goto exit;
  396. }
  397. DPRINTF(("TCP_Server: Accepted connection\n"));
  398. scp = PR_NEW(Serve_Client_Param);
  399. if (scp == NULL) {
  400. fprintf(stderr,"prsocket_test: PR_NEW failed\n");
  401. goto exit;
  402. }
  403. /*
  404. * Start a Serve_Client thread for each incoming connection
  405. */
  406. scp->sockfd = newsockfd;
  407. scp->datalen = sp->datalen;
  408. t = create_new_thread(PR_USER_THREAD,
  409. Serve_Client, (void *)scp,
  410. PR_PRIORITY_NORMAL,
  411. PR_LOCAL_THREAD,
  412. PR_UNJOINABLE_THREAD,
  413. 0, i);
  414. if (t == NULL) {
  415. fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
  416. failed_already=1;
  417. goto exit;
  418. }
  419. DPRINTF(("TCP_Server: Created Serve_Client = 0x%lx\n", t));
  420. }
  421. exit:
  422. if (sockfd) {
  423. PR_Close(sockfd);
  424. }
  425. /*
  426. * Decrement exit_counter and notify parent thread
  427. */
  428. PR_EnterMonitor(sp->exit_mon);
  429. --(*sp->exit_counter);
  430. PR_Notify(sp->exit_mon);
  431. PR_ExitMonitor(sp->exit_mon);
  432. DPRINTF(("TCP_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
  433. }
  434. /*
  435. * UDP Server
  436. * Server Thread
  437. * Bind an address to a socket, read data from clients and send data
  438. * back to clients
  439. */
  440. static void PR_CALLBACK
  441. UDP_Server(void *arg)
  442. {
  443. Server_Param *sp = (Server_Param *) arg;
  444. PRFileDesc *sockfd;
  445. buffer *in_buf;
  446. PRNetAddr netaddr;
  447. PRInt32 bytes, i, rv = 0;
  448. bytes = sp->datalen;
  449. /*
  450. * Create a udp socket
  451. */
  452. if ((sockfd = PR_OpenUDPSocket(server_domain)) == NULL) {
  453. fprintf(stderr,"prsocket_test: PR_NewUDPSocket failed\n");
  454. failed_already=1;
  455. return;
  456. }
  457. memset(&netaddr, 0, sizeof(netaddr));
  458. if (PR_SetNetAddr(PR_IpAddrAny, server_domain, UDP_SERVER_PORT,
  459. &netaddr) == PR_FAILURE) {
  460. fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
  461. failed_already=1;
  462. return;
  463. }
  464. /*
  465. * try a few times to bind server's address, if addresses are in
  466. * use
  467. */
  468. i = 0;
  469. while (PR_Bind(sockfd, &netaddr) < 0) {
  470. if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
  471. netaddr.inet.port += 2;
  472. if (i++ < SERVER_MAX_BIND_COUNT) {
  473. continue;
  474. }
  475. }
  476. fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
  477. perror("PR_Bind");
  478. failed_already=1;
  479. return;
  480. }
  481. if (PR_GetSockName(sockfd, &netaddr) < 0) {
  482. fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
  483. failed_already=1;
  484. return;
  485. }
  486. DPRINTF(("PR_Bind: UDP Server netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
  487. netaddr.inet.ip, netaddr.inet.port));
  488. /*
  489. * We can't use the IP address returned by PR_GetSockName in
  490. * netaddr.inet.ip because netaddr.inet.ip is returned
  491. * as 0 (= PR_INADDR_ANY).
  492. */
  493. if (PR_SetNetAddr(PR_IpAddrLoopback, client_domain,
  494. PR_ntohs(PR_NetAddrInetPort(&netaddr)),
  495. &udp_server_addr) == PR_FAILURE) {
  496. fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
  497. failed_already=1;
  498. return;
  499. }
  500. if ((client_domain == PR_AF_INET6) && (server_domain == PR_AF_INET))
  501. PR_ConvertIPv4AddrToIPv6(PR_htonl(INADDR_LOOPBACK),
  502. &udp_server_addr.ipv6.ip);
  503. /*
  504. * Wake up parent thread because server address is bound and made
  505. * available in the global variable 'udp_server_addr'
  506. */
  507. PR_PostSem(sp->addr_sem);
  508. bytes = sp->datalen;
  509. in_buf = PR_NEW(buffer);
  510. if (in_buf == NULL) {
  511. fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
  512. failed_already=1;
  513. return;
  514. }
  515. /*
  516. * Receive datagrams from clients and send them back, unmodified, to the
  517. * clients
  518. */
  519. memset(&netaddr, 0, sizeof(netaddr));
  520. for (i = 0; i < (num_udp_clients * num_udp_datagrams_per_client); i++) {
  521. DPRINTF(("UDP_Server: calling PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
  522. netaddr.inet.ip, netaddr.inet.port, bytes, in_buf->data,
  523. in_buf->data[0]));
  524. rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
  525. PR_INTERVAL_NO_TIMEOUT);
  526. DPRINTF(("UDP_Server: PR_RecvFrom client - ip = 0x%lx, port = %d bytes = %d inbuf = 0x%lx, inbuf[0] = 0x%lx\n",
  527. netaddr.inet.ip, netaddr.inet.port, rv, in_buf->data,
  528. in_buf->data[0]));
  529. if (rv != bytes) {
  530. return;
  531. }
  532. rv = PR_SendTo(sockfd, in_buf->data, bytes, 0, &netaddr,
  533. PR_INTERVAL_NO_TIMEOUT);
  534. if (rv != bytes) {
  535. return;
  536. }
  537. }
  538. PR_DELETE(in_buf);
  539. PR_Close(sockfd);
  540. /*
  541. * Decrement exit_counter and notify parent thread
  542. */
  543. PR_EnterMonitor(sp->exit_mon);
  544. --(*sp->exit_counter);
  545. PR_Notify(sp->exit_mon);
  546. PR_ExitMonitor(sp->exit_mon);
  547. DPRINTF(("UDP_Server [0x%x] exiting\n", PR_GetCurrentThread()));
  548. }
  549. /*
  550. * TCP_Client
  551. * Client Thread
  552. * Connect to the server at the address specified in the argument.
  553. * Fill in a buffer, write data to server, read it back and check
  554. * for data corruption.
  555. * Close the socket for server connection
  556. */
  557. static void PR_CALLBACK
  558. TCP_Client(void *arg)
  559. {
  560. Client_Param *cp = (Client_Param *) arg;
  561. PRFileDesc *sockfd;
  562. buffer *in_buf, *out_buf;
  563. union PRNetAddr netaddr;
  564. PRInt32 bytes, i, j;
  565. bytes = cp->datalen;
  566. out_buf = PR_NEW(buffer);
  567. if (out_buf == NULL) {
  568. fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
  569. failed_already=1;
  570. return;
  571. }
  572. in_buf = PR_NEW(buffer);
  573. if (in_buf == NULL) {
  574. fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
  575. failed_already=1;
  576. return;
  577. }
  578. netaddr = cp->server_addr;
  579. for (i = 0; i < num_tcp_connections_per_client; i++) {
  580. if ((sockfd = PR_OpenTCPSocket(client_domain)) == NULL) {
  581. fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n");
  582. failed_already=1;
  583. return;
  584. }
  585. if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0) {
  586. fprintf(stderr, "PR_Connect failed: (%ld, %ld)\n",
  587. PR_GetError(), PR_GetOSError());
  588. failed_already=1;
  589. return;
  590. }
  591. for (j = 0; j < num_tcp_mesgs_per_connection; j++) {
  592. /*
  593. * fill in random data
  594. */
  595. memset(out_buf->data, ((PRInt32) (&netaddr)) + i + j, bytes);
  596. /*
  597. * write to server
  598. */
  599. #ifdef WINNT
  600. if (test_cancelio && (j == 0)) {
  601. PR_Sleep(PR_SecondsToInterval(12));
  602. }
  603. #endif
  604. if (writen(sockfd, out_buf->data, bytes) < bytes) {
  605. fprintf(stderr,"prsocket_test: ERROR - TCP_Client:writen\n");
  606. failed_already=1;
  607. return;
  608. }
  609. DPRINTF(("TCP Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
  610. PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
  611. if (readn(sockfd, in_buf->data, bytes) < bytes) {
  612. fprintf(stderr,"prsocket_test: ERROR - TCP_Client:readn\n");
  613. failed_already=1;
  614. return;
  615. }
  616. /*
  617. * verify the data read
  618. */
  619. if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
  620. fprintf(stderr,"prsocket_test: ERROR - data corruption\n");
  621. failed_already=1;
  622. return;
  623. }
  624. }
  625. /*
  626. * shutdown reads and writes
  627. */
  628. if (PR_Shutdown(sockfd, PR_SHUTDOWN_BOTH) < 0) {
  629. fprintf(stderr,"prsocket_test: ERROR - PR_Shutdown\n");
  630. failed_already=1;
  631. }
  632. PR_Close(sockfd);
  633. }
  634. PR_DELETE(out_buf);
  635. PR_DELETE(in_buf);
  636. /*
  637. * Decrement exit_counter and notify parent thread
  638. */
  639. PR_EnterMonitor(cp->exit_mon);
  640. --(*cp->exit_counter);
  641. PR_Notify(cp->exit_mon);
  642. PR_ExitMonitor(cp->exit_mon);
  643. DPRINTF(("TCP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
  644. }
  645. /*
  646. * UDP_Client
  647. * Client Thread
  648. * Create a socket and bind an address
  649. * Communicate with the server at the address specified in the argument.
  650. * Fill in a buffer, write data to server, read it back and check
  651. * for data corruption.
  652. * Close the socket
  653. */
  654. static void PR_CALLBACK
  655. UDP_Client(void *arg)
  656. {
  657. Client_Param *cp = (Client_Param *) arg;
  658. PRFileDesc *sockfd;
  659. buffer *in_buf, *out_buf;
  660. union PRNetAddr netaddr;
  661. PRInt32 bytes, i, rv;
  662. bytes = cp->datalen;
  663. out_buf = PR_NEW(buffer);
  664. if (out_buf == NULL) {
  665. fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
  666. failed_already=1;
  667. return;
  668. }
  669. in_buf = PR_NEW(buffer);
  670. if (in_buf == NULL) {
  671. fprintf(stderr,"prsocket_test: failed to alloc buffer struct\n");
  672. failed_already=1;
  673. return;
  674. }
  675. if ((sockfd = PR_OpenUDPSocket(client_domain)) == NULL) {
  676. fprintf(stderr,"prsocket_test: PR_OpenUDPSocket failed\n");
  677. failed_already=1;
  678. return;
  679. }
  680. /*
  681. * bind an address for the client, let the system chose the port
  682. * number
  683. */
  684. memset(&netaddr, 0, sizeof(netaddr));
  685. if (PR_SetNetAddr(PR_IpAddrAny, client_domain, 0,
  686. &netaddr) == PR_FAILURE) {
  687. fprintf(stderr,"prsocket_test: PR_SetNetAddr failed\n");
  688. failed_already=1;
  689. return;
  690. }
  691. if (PR_Bind(sockfd, &netaddr) < 0) {
  692. fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
  693. perror("PR_Bind");
  694. return;
  695. }
  696. if (PR_GetSockName(sockfd, &netaddr) < 0) {
  697. fprintf(stderr,"prsocket_test: ERROR - PR_GetSockName failed\n");
  698. failed_already=1;
  699. return;
  700. }
  701. DPRINTF(("PR_Bind: UDP Client netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
  702. netaddr.inet.ip, netaddr.inet.port));
  703. netaddr = cp->server_addr;
  704. if (cp->udp_connect) {
  705. if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0) {
  706. fprintf(stderr,"prsocket_test: PR_Connect failed\n");
  707. failed_already=1;
  708. return;
  709. }
  710. }
  711. for (i = 0; i < num_udp_datagrams_per_client; i++) {
  712. /*
  713. * fill in random data
  714. */
  715. DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx bytes = 0x%lx\n",
  716. PR_GetCurrentThread(), out_buf->data, bytes));
  717. memset(out_buf->data, ((PRInt32) (&netaddr)) + i, bytes);
  718. /*
  719. * write to server
  720. */
  721. if (cp->udp_connect)
  722. rv = PR_Send(sockfd, out_buf->data, bytes, 0,
  723. PR_INTERVAL_NO_TIMEOUT);
  724. else
  725. rv = PR_SendTo(sockfd, out_buf->data, bytes, 0, &netaddr,
  726. PR_INTERVAL_NO_TIMEOUT);
  727. if (rv != bytes) {
  728. return;
  729. }
  730. DPRINTF(("UDP_Client [0x%lx]: out_buf = 0x%lx out_buf[0] = 0x%lx\n",
  731. PR_GetCurrentThread(), out_buf, (*((int *) out_buf->data))));
  732. if (cp->udp_connect)
  733. rv = PR_Recv(sockfd, in_buf->data, bytes, 0,
  734. PR_INTERVAL_NO_TIMEOUT);
  735. else
  736. rv = PR_RecvFrom(sockfd, in_buf->data, bytes, 0, &netaddr,
  737. PR_INTERVAL_NO_TIMEOUT);
  738. if (rv != bytes) {
  739. return;
  740. }
  741. DPRINTF(("UDP_Client [0x%lx]: in_buf = 0x%lx in_buf[0] = 0x%lx\n",
  742. PR_GetCurrentThread(), in_buf, (*((int *) in_buf->data))));
  743. /*
  744. * verify the data read
  745. */
  746. if (memcmp(in_buf->data, out_buf->data, bytes) != 0) {
  747. fprintf(stderr,"prsocket_test: ERROR - UDP data corruption\n");
  748. failed_already=1;
  749. return;
  750. }
  751. }
  752. PR_Close(sockfd);
  753. PR_DELETE(in_buf);
  754. PR_DELETE(out_buf);
  755. /*
  756. * Decrement exit_counter and notify parent thread
  757. */
  758. PR_EnterMonitor(cp->exit_mon);
  759. --(*cp->exit_counter);
  760. PR_Notify(cp->exit_mon);
  761. PR_ExitMonitor(cp->exit_mon);
  762. PR_DELETE(cp);
  763. DPRINTF(("UDP_Client [0x%x] exiting\n", PR_GetCurrentThread()));
  764. }
  765. /*
  766. * TCP_Socket_Client_Server_Test - concurrent server test
  767. *
  768. * One server and several clients are started
  769. * Each client connects to the server and sends a chunk of data
  770. * For each connection, server starts another thread to read the data
  771. * from the client and send it back to the client, unmodified.
  772. * Each client checks that data received from server is same as the
  773. * data it sent to the server.
  774. *
  775. */
  776. static PRInt32
  777. TCP_Socket_Client_Server_Test(void)
  778. {
  779. int i;
  780. PRThread *t;
  781. PRSemaphore *server_sem;
  782. Server_Param *sparamp;
  783. Client_Param *cparamp;
  784. PRMonitor *mon2;
  785. PRInt32 datalen;
  786. datalen = tcp_mesg_size;
  787. thread_count = 0;
  788. /*
  789. * start the server thread
  790. */
  791. sparamp = PR_NEW(Server_Param);
  792. if (sparamp == NULL) {
  793. fprintf(stderr,"prsocket_test: PR_NEW failed\n");
  794. failed_already=1;
  795. return -1;
  796. }
  797. server_sem = PR_NewSem(0);
  798. if (server_sem == NULL) {
  799. fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
  800. failed_already=1;
  801. return -1;
  802. }
  803. mon2 = PR_NewMonitor();
  804. if (mon2 == NULL) {
  805. fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
  806. failed_already=1;
  807. return -1;
  808. }
  809. PR_EnterMonitor(mon2);
  810. sparamp->addr_sem = server_sem;
  811. sparamp->exit_mon = mon2;
  812. sparamp->exit_counter = &thread_count;
  813. sparamp->datalen = datalen;
  814. t = PR_CreateThread(PR_USER_THREAD,
  815. TCP_Server, (void *)sparamp,
  816. PR_PRIORITY_NORMAL,
  817. PR_LOCAL_THREAD,
  818. PR_UNJOINABLE_THREAD,
  819. 0);
  820. if (t == NULL) {
  821. fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
  822. failed_already=1;
  823. return -1;
  824. }
  825. DPRINTF(("Created TCP server = 0x%lx\n", t));
  826. thread_count++;
  827. /*
  828. * wait till the server address is setup
  829. */
  830. PR_WaitSem(server_sem);
  831. /*
  832. * Now start a bunch of client threads
  833. */
  834. cparamp = PR_NEW(Client_Param);
  835. if (cparamp == NULL) {
  836. fprintf(stderr,"prsocket_test: PR_NEW failed\n");
  837. failed_already=1;
  838. return -1;
  839. }
  840. cparamp->server_addr = tcp_server_addr;
  841. cparamp->exit_mon = mon2;
  842. cparamp->exit_counter = &thread_count;
  843. cparamp->datalen = datalen;
  844. for (i = 0; i < num_tcp_clients; i++) {
  845. t = create_new_thread(PR_USER_THREAD,
  846. TCP_Client, (void *) cparamp,
  847. PR_PRIORITY_NORMAL,
  848. PR_LOCAL_THREAD,
  849. PR_UNJOINABLE_THREAD,
  850. 0, i);
  851. if (t == NULL) {
  852. fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
  853. failed_already=1;
  854. return -1;
  855. }
  856. DPRINTF(("Created TCP client = 0x%lx\n", t));
  857. thread_count++;
  858. }
  859. /* Wait for server and client threads to exit */
  860. while (thread_count) {
  861. PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
  862. DPRINTF(("TCP Server - thread_count = %d\n", thread_count));
  863. }
  864. PR_ExitMonitor(mon2);
  865. printf("%30s","TCP_Socket_Client_Server_Test:");
  866. printf("%2ld Server %2ld Clients %2ld connections_per_client\n",1l,
  867. num_tcp_clients, num_tcp_connections_per_client);
  868. printf("%30s %2ld messages_per_connection %4ld bytes_per_message\n",":",
  869. num_tcp_mesgs_per_connection, tcp_mesg_size);
  870. return 0;
  871. }
  872. /*
  873. * UDP_Socket_Client_Server_Test - iterative server test
  874. *
  875. * One server and several clients are started
  876. * Each client connects to the server and sends a chunk of data
  877. * For each connection, server starts another thread to read the data
  878. * from the client and send it back to the client, unmodified.
  879. * Each client checks that data received from server is same as the
  880. * data it sent to the server.
  881. *
  882. */
  883. static PRInt32
  884. UDP_Socket_Client_Server_Test(void)
  885. {
  886. int i;
  887. PRThread *t;
  888. PRSemaphore *server_sem;
  889. Server_Param *sparamp;
  890. Client_Param *cparamp;
  891. PRMonitor *mon2;
  892. PRInt32 datalen;
  893. PRInt32 udp_connect = 1;
  894. datalen = udp_datagram_size;
  895. thread_count = 0;
  896. /*
  897. * start the server thread
  898. */
  899. sparamp = PR_NEW(Server_Param);
  900. if (sparamp == NULL) {
  901. fprintf(stderr,"prsocket_test: PR_NEW failed\n");
  902. failed_already=1;
  903. return -1;
  904. }
  905. server_sem = PR_NewSem(0);
  906. if (server_sem == NULL) {
  907. fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
  908. failed_already=1;
  909. return -1;
  910. }
  911. mon2 = PR_NewMonitor();
  912. if (mon2 == NULL) {
  913. fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
  914. failed_already=1;
  915. return -1;
  916. }
  917. PR_EnterMonitor(mon2);
  918. sparamp->addr_sem = server_sem;
  919. sparamp->exit_mon = mon2;
  920. sparamp->exit_counter = &thread_count;
  921. sparamp->datalen = datalen;
  922. DPRINTF(("Creating UDP server"));
  923. t = PR_CreateThread(PR_USER_THREAD,
  924. UDP_Server, (void *)sparamp,
  925. PR_PRIORITY_NORMAL,
  926. PR_LOCAL_THREAD,
  927. PR_UNJOINABLE_THREAD,
  928. 0);
  929. if (t == NULL) {
  930. fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
  931. failed_already=1;
  932. return -1;
  933. }
  934. thread_count++;
  935. /*
  936. * wait till the server address is setup
  937. */
  938. PR_WaitSem(server_sem);
  939. /*
  940. * Now start a bunch of client threads
  941. */
  942. for (i = 0; i < num_udp_clients; i++) {
  943. cparamp = PR_NEW(Client_Param);
  944. if (cparamp == NULL) {
  945. fprintf(stderr,"prsocket_test: PR_NEW failed\n");
  946. failed_already=1;
  947. return -1;
  948. }
  949. cparamp->server_addr = udp_server_addr;
  950. cparamp->exit_mon = mon2;
  951. cparamp->exit_counter = &thread_count;
  952. cparamp->datalen = datalen;
  953. /*
  954. * Cause every other client thread to connect udp sockets
  955. */
  956. cparamp->udp_connect = udp_connect;
  957. if (udp_connect) {
  958. udp_connect = 0;
  959. }
  960. else {
  961. udp_connect = 1;
  962. }
  963. DPRINTF(("Creating UDP client %d\n", i));
  964. t = PR_CreateThread(PR_USER_THREAD,
  965. UDP_Client, (void *) cparamp,
  966. PR_PRIORITY_NORMAL,
  967. PR_LOCAL_THREAD,
  968. PR_UNJOINABLE_THREAD,
  969. 0);
  970. if (t == NULL) {
  971. fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
  972. failed_already=1;
  973. return -1;
  974. }
  975. thread_count++;
  976. }
  977. /* Wait for server and client threads to exit */
  978. while (thread_count) {
  979. PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
  980. DPRINTF(("UDP Server - thread_count = %d\n", thread_count));
  981. }
  982. PR_ExitMonitor(mon2);
  983. printf("%30s","UDP_Socket_Client_Server_Test: ");
  984. printf("%2ld Server %2ld Clients\n",1l, num_udp_clients);
  985. printf("%30s %2ld datagrams_per_client %4ld bytes_per_datagram\n",":",
  986. num_udp_datagrams_per_client, udp_datagram_size);
  987. return 0;
  988. }
  989. static PRFileDesc *small_file_fd, *large_file_fd;
  990. static void *small_file_addr, *small_file_header, *large_file_addr;
  991. static void *small_file_trailer, *large_file_header, *large_file_trailer;
  992. /*
  993. * TransmitFile_Client
  994. * Client Thread
  995. */
  996. static void
  997. TransmitFile_Client(void *arg)
  998. {
  999. PRFileDesc *sockfd;
  1000. union PRNetAddr netaddr;
  1001. char *small_buf, *large_buf;
  1002. Client_Param *cp = (Client_Param *) arg;
  1003. PRInt32 rlen;
  1004. small_buf = (char*)PR_Malloc(SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE +
  1005. SMALL_FILE_TRAILER_SIZE);
  1006. if (small_buf == NULL) {
  1007. fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
  1008. failed_already=1;
  1009. return;
  1010. }
  1011. large_buf = (char*)PR_Malloc(LARGE_FILE_SIZE + LARGE_FILE_HEADER_SIZE +
  1012. LARGE_FILE_TRAILER_SIZE);
  1013. if (large_buf == NULL) {
  1014. fprintf(stderr,"prsocket_test: failed to alloc buffer\n");
  1015. failed_already=1;
  1016. return;
  1017. }
  1018. netaddr.inet.family = cp->server_addr.inet.family;
  1019. netaddr.inet.port = cp->server_addr.inet.port;
  1020. netaddr.inet.ip = cp->server_addr.inet.ip;
  1021. if ((sockfd = PR_NewTCPSocket()) == NULL) {
  1022. fprintf(stderr,"prsocket_test: PR_NewTCPSocket failed\n");
  1023. failed_already=1;
  1024. return;
  1025. }
  1026. if (PR_Connect(sockfd, &netaddr,PR_INTERVAL_NO_TIMEOUT) < 0) {
  1027. fprintf(stderr,"prsocket_test: PR_Connect failed\n");
  1028. failed_already=1;
  1029. return;
  1030. }
  1031. /*
  1032. * read the small file and verify the data
  1033. */
  1034. if (readn(sockfd, small_buf, SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)
  1035. != (SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE)) {
  1036. fprintf(stderr,
  1037. "prsocket_test: TransmitFile_Client failed to receive file\n");
  1038. failed_already=1;
  1039. return;
  1040. }
  1041. #if defined(XP_UNIX)
  1042. /* File transmission test can not be done because of large file's size */
  1043. if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0) {
  1044. fprintf(stderr,
  1045. "prsocket_test: TransmitFile_Client ERROR - small file header data corruption\n");
  1046. failed_already=1;
  1047. return;
  1048. }
  1049. if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
  1050. SMALL_FILE_SIZE) != 0) {
  1051. fprintf(stderr,
  1052. "prsocket_test: TransmitFile_Client ERROR - small file data corruption\n");
  1053. failed_already=1;
  1054. return;
  1055. }
  1056. #endif
  1057. /*
  1058. * read the large file and verify the data
  1059. */
  1060. if (readn(sockfd, large_buf, LARGE_FILE_SIZE) != LARGE_FILE_SIZE) {
  1061. fprintf(stderr,
  1062. "prsocket_test: TransmitFile_Client failed to receive file\n");
  1063. failed_already=1;
  1064. return;
  1065. }
  1066. #if defined(XP_UNIX)
  1067. if (memcmp(large_file_addr, large_buf, LARGE_FILE_SIZE) != 0) {
  1068. fprintf(stderr,
  1069. "prsocket_test: TransmitFile_Client ERROR - large file data corruption\n");
  1070. failed_already=1;
  1071. }
  1072. #endif
  1073. /*
  1074. * receive data from PR_SendFile
  1075. */
  1076. /*
  1077. * case 1: small file with header and trailer
  1078. */
  1079. rlen = SMALL_FILE_SIZE + SMALL_FILE_HEADER_SIZE +
  1080. SMALL_FILE_TRAILER_SIZE;
  1081. if (readn(sockfd, small_buf, rlen) != rlen) {
  1082. fprintf(stderr,
  1083. "prsocket_test: SendFile_Client failed to receive file\n");
  1084. failed_already=1;
  1085. return;
  1086. }
  1087. #if defined(XP_UNIX)
  1088. if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0) {
  1089. fprintf(stderr,
  1090. "SendFile 1. ERROR - small file header corruption\n");
  1091. failed_already=1;
  1092. return;
  1093. }
  1094. if (memcmp(small_file_addr, small_buf + SMALL_FILE_HEADER_SIZE,
  1095. SMALL_FILE_SIZE) != 0) {
  1096. fprintf(stderr,
  1097. "SendFile 1. ERROR - small file data corruption\n");
  1098. failed_already=1;
  1099. return;
  1100. }
  1101. if (memcmp(small_file_trailer,
  1102. small_buf + SMALL_FILE_HEADER_SIZE + SMALL_FILE_SIZE,
  1103. SMALL_FILE_TRAILER_SIZE) != 0) {
  1104. fprintf(stderr,
  1105. "SendFile 1. ERROR - small file trailer corruption\n");
  1106. failed_already=1;
  1107. return;
  1108. }
  1109. #endif
  1110. /*
  1111. * case 2: partial large file at zero offset, file with header and trailer
  1112. */
  1113. rlen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE +
  1114. LARGE_FILE_TRAILER_SIZE;
  1115. if (readn(sockfd, large_buf, rlen) != rlen) {
  1116. fprintf(stderr,
  1117. "prsocket_test: SendFile_Client failed to receive file\n");
  1118. failed_already=1;
  1119. return;
  1120. }
  1121. #if defined(XP_UNIX)
  1122. if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0) {
  1123. fprintf(stderr,
  1124. "SendFile 2. ERROR - large file header corruption\n");
  1125. failed_already=1;
  1126. return;
  1127. }
  1128. if (memcmp(large_file_addr, large_buf + LARGE_FILE_HEADER_SIZE,
  1129. LARGE_FILE_LEN_1) != 0) {
  1130. fprintf(stderr,
  1131. "SendFile 2. ERROR - large file data corruption\n");
  1132. failed_already=1;
  1133. return;
  1134. }
  1135. if (memcmp(large_file_trailer,
  1136. large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_1,
  1137. LARGE_FILE_TRAILER_SIZE) != 0) {
  1138. fprintf(stderr,
  1139. "SendFile 2. ERROR - large file trailer corruption\n");
  1140. failed_already=1;
  1141. return;
  1142. }
  1143. #endif
  1144. /*
  1145. * case 3: partial small file at non-zero offset, with header
  1146. */
  1147. rlen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE;
  1148. if (readn(sockfd, small_buf, rlen) != rlen) {
  1149. fprintf(stderr,
  1150. "prsocket_test: SendFile_Client failed to receive file\n");
  1151. failed_already=1;
  1152. return;
  1153. }
  1154. #if defined(XP_UNIX)
  1155. if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0) {
  1156. fprintf(stderr,
  1157. "SendFile 3. ERROR - small file header corruption\n");
  1158. failed_already=1;
  1159. return;
  1160. }
  1161. if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_1,
  1162. small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_1) != 0) {
  1163. fprintf(stderr,
  1164. "SendFile 3. ERROR - small file data corruption\n");
  1165. failed_already=1;
  1166. return;
  1167. }
  1168. #endif
  1169. /*
  1170. * case 4: partial small file at non-zero offset, with trailer
  1171. */
  1172. rlen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE;
  1173. if (readn(sockfd, small_buf, rlen) != rlen) {
  1174. fprintf(stderr,
  1175. "prsocket_test: SendFile_Client failed to receive file\n");
  1176. failed_already=1;
  1177. return;
  1178. }
  1179. #if defined(XP_UNIX)
  1180. if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_2, small_buf,
  1181. SMALL_FILE_LEN_2) != 0) {
  1182. fprintf(stderr,
  1183. "SendFile 4. ERROR - small file data corruption\n");
  1184. failed_already=1;
  1185. return;
  1186. }
  1187. if (memcmp(small_file_trailer, small_buf + SMALL_FILE_LEN_2,
  1188. SMALL_FILE_TRAILER_SIZE) != 0) {
  1189. fprintf(stderr,
  1190. "SendFile 4. ERROR - small file trailer corruption\n");
  1191. failed_already=1;
  1192. return;
  1193. }
  1194. #endif
  1195. /*
  1196. * case 5: partial large file at non-zero offset, file with header
  1197. */
  1198. rlen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE;
  1199. if (readn(sockfd, large_buf, rlen) != rlen) {
  1200. fprintf(stderr,
  1201. "prsocket_test: SendFile_Client failed to receive file\n");
  1202. failed_already=1;
  1203. return;
  1204. }
  1205. #if defined(XP_UNIX)
  1206. if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0) {
  1207. fprintf(stderr,
  1208. "SendFile 5. ERROR - large file header corruption\n");
  1209. failed_already=1;
  1210. return;
  1211. }
  1212. if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_2,
  1213. large_buf + LARGE_FILE_HEADER_SIZE,
  1214. LARGE_FILE_LEN_2) != 0) {
  1215. fprintf(stderr,
  1216. "SendFile 5. ERROR - large file data corruption\n");
  1217. failed_already=1;
  1218. return;
  1219. }
  1220. #endif
  1221. /*
  1222. * case 6: partial small file at non-zero offset, with header
  1223. */
  1224. rlen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE;
  1225. if (readn(sockfd, small_buf, rlen) != rlen) {
  1226. fprintf(stderr,
  1227. "prsocket_test: SendFile_Client failed to receive file\n");
  1228. failed_already=1;
  1229. return;
  1230. }
  1231. #if defined(XP_UNIX)
  1232. if (memcmp(small_file_header, small_buf, SMALL_FILE_HEADER_SIZE) != 0) {
  1233. fprintf(stderr,
  1234. "SendFile 6. ERROR - small file header corruption\n");
  1235. return;
  1236. }
  1237. if (memcmp((char *) small_file_addr + SMALL_FILE_OFFSET_3,
  1238. small_buf + SMALL_FILE_HEADER_SIZE, SMALL_FILE_LEN_3) != 0) {
  1239. #if 0
  1240. char *i, *j;
  1241. int k;
  1242. i = (char *) small_file_addr + SMALL_FILE_OFFSET_3;
  1243. j = small_buf + SMALL_FILE_HEADER_SIZE;
  1244. k = SMALL_FILE_LEN_3;
  1245. while (k-- > 0) {
  1246. if (*i++ != *j++)
  1247. printf("i = %d j = %d\n",
  1248. (int) (i - ((char *) small_file_addr + SMALL_FILE_OFFSET_3)),
  1249. (int) (j - (small_buf + SMALL_FILE_HEADER_SIZE)));
  1250. }
  1251. #endif
  1252. fprintf(stderr,
  1253. "SendFile 6. ERROR - small file data corruption\n");
  1254. failed_already=1;
  1255. return;
  1256. }
  1257. #endif
  1258. /*
  1259. * case 7: partial large file at non-zero offset, with header
  1260. */
  1261. rlen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE;
  1262. if (readn(sockfd, large_buf, rlen) != rlen) {
  1263. fprintf(stderr,
  1264. "prsocket_test: SendFile_Client failed to receive file\n");
  1265. failed_already=1;
  1266. return;
  1267. }
  1268. #if defined(XP_UNIX)
  1269. if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0) {
  1270. fprintf(stderr,
  1271. "SendFile 7. ERROR - large file header corruption\n");
  1272. failed_already=1;
  1273. return;
  1274. }
  1275. if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_3,
  1276. large_buf + LARGE_FILE_HEADER_SIZE,
  1277. LARGE_FILE_LEN_3) != 0) {
  1278. fprintf(stderr,
  1279. "SendFile 7. ERROR - large file data corruption\n");
  1280. failed_already=1;
  1281. return;
  1282. }
  1283. #endif
  1284. /*
  1285. * case 8: partial large file at non-zero, page-aligned offset, with
  1286. * header and trailer
  1287. */
  1288. rlen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE +
  1289. LARGE_FILE_TRAILER_SIZE;
  1290. if (readn(sockfd, large_buf, rlen) != rlen) {
  1291. fprintf(stderr,
  1292. "prsocket_test: SendFile_Client failed to receive file\n");
  1293. failed_already=1;
  1294. return;
  1295. }
  1296. #if defined(XP_UNIX)
  1297. if (memcmp(large_file_header, large_buf, LARGE_FILE_HEADER_SIZE) != 0) {
  1298. fprintf(stderr,
  1299. "SendFile 2. ERROR - large file header corruption\n");
  1300. failed_already=1;
  1301. return;
  1302. }
  1303. if (memcmp((char *)large_file_addr + LARGE_FILE_OFFSET_4,
  1304. large_buf + LARGE_FILE_HEADER_SIZE,
  1305. LARGE_FILE_LEN_4) != 0) {
  1306. fprintf(stderr,
  1307. "SendFile 2. ERROR - large file data corruption\n");
  1308. failed_already=1;
  1309. return;
  1310. }
  1311. if (memcmp(large_file_trailer,
  1312. large_buf + LARGE_FILE_HEADER_SIZE + LARGE_FILE_LEN_4,
  1313. LARGE_FILE_TRAILER_SIZE) != 0) {
  1314. fprintf(stderr,
  1315. "SendFile 2. ERROR - large file trailer corruption\n");
  1316. failed_already=1;
  1317. return;
  1318. }
  1319. #endif
  1320. PR_DELETE(small_buf);
  1321. PR_DELETE(large_buf);
  1322. PR_Close(sockfd);
  1323. /*
  1324. * Decrement exit_counter and notify parent thread
  1325. */
  1326. PR_EnterMonitor(cp->exit_mon);
  1327. --(*cp->exit_counter);
  1328. PR_Notify(cp->exit_mon);
  1329. PR_ExitMonitor(cp->exit_mon);
  1330. DPRINTF(("TransmitFile_Client [0x%lx] exiting\n", PR_GetCurrentThread()));
  1331. }
  1332. /*
  1333. * Serve_TransmitFile_Client
  1334. * Thread, started by the server, for serving a client connection.
  1335. * Trasmits a small file, with a header, and a large file, without
  1336. * a header
  1337. */
  1338. static void
  1339. Serve_TransmitFile_Client(void *arg)
  1340. {
  1341. Serve_Client_Param *scp = (Serve_Client_Param *) arg;
  1342. PRFileDesc *sockfd;
  1343. PRInt32 bytes;
  1344. PRFileDesc *local_small_file_fd=NULL;
  1345. PRFileDesc *local_large_file_fd=NULL;
  1346. PRSendFileData sfd;
  1347. PRInt32 slen;
  1348. sockfd = scp->sockfd;
  1349. local_small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDONLY,0);
  1350. if (local_small_file_fd == NULL) {
  1351. fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n",
  1352. SMALL_FILE_NAME);
  1353. failed_already=1;
  1354. goto done;
  1355. }
  1356. local_large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDONLY,0);
  1357. if (local_large_file_fd == NULL) {
  1358. fprintf(stderr,"prsocket_test failed to open file for transmitting %s\n",
  1359. LARGE_FILE_NAME);
  1360. failed_already=1;
  1361. goto done;
  1362. }
  1363. bytes = PR_TransmitFile(sockfd, local_small_file_fd, small_file_header,
  1364. SMALL_FILE_HEADER_SIZE, PR_TRANSMITFILE_KEEP_OPEN,
  1365. PR_INTERVAL_NO_TIMEOUT);
  1366. if (bytes != (SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE)) {
  1367. fprintf(stderr,
  1368. "prsocet_test: PR_TransmitFile failed: (%ld, %ld)\n",
  1369. PR_GetError(), PR_GetOSError());
  1370. failed_already=1;
  1371. }
  1372. bytes = PR_TransmitFile(sockfd, local_large_file_fd, NULL, 0,
  1373. PR_TRANSMITFILE_KEEP_OPEN, PR_INTERVAL_NO_TIMEOUT);
  1374. if (bytes != LARGE_FILE_SIZE) {
  1375. fprintf(stderr,
  1376. "prsocket_test: PR_TransmitFile failed: (%ld, %ld)\n",
  1377. PR_GetError(), PR_GetOSError());
  1378. failed_already=1;
  1379. }
  1380. /*
  1381. * PR_SendFile test cases
  1382. */
  1383. /*
  1384. * case 1: small file with header and trailer
  1385. */
  1386. sfd.fd = local_small_file_fd;
  1387. sfd.file_offset = 0;
  1388. sfd.file_nbytes = 0;
  1389. sfd.header = small_file_header;
  1390. sfd.hlen = SMALL_FILE_HEADER_SIZE;
  1391. sfd.trailer = small_file_trailer;
  1392. sfd.tlen = SMALL_FILE_TRAILER_SIZE;
  1393. bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
  1394. PR_INTERVAL_NO_TIMEOUT);
  1395. slen = SMALL_FILE_SIZE+ SMALL_FILE_HEADER_SIZE +
  1396. SMALL_FILE_TRAILER_SIZE;
  1397. if (bytes != slen) {
  1398. fprintf(stderr,
  1399. "socket: Error - 1. PR_SendFile send_size = %d, bytes sent = %d\n",
  1400. slen, bytes);
  1401. fprintf(stderr,
  1402. "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
  1403. PR_GetError(), PR_GetOSError());
  1404. failed_already=1;
  1405. }
  1406. /*
  1407. * case 2: partial large file at zero offset, file with header and trailer
  1408. */
  1409. sfd.fd = local_large_file_fd;
  1410. sfd.file_offset = 0;
  1411. sfd.file_nbytes = LARGE_FILE_LEN_1;
  1412. sfd.header = large_file_header;
  1413. sfd.hlen = LARGE_FILE_HEADER_SIZE;
  1414. sfd.trailer = large_file_trailer;
  1415. sfd.tlen = LARGE_FILE_TRAILER_SIZE;
  1416. bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
  1417. PR_INTERVAL_NO_TIMEOUT);
  1418. slen = LARGE_FILE_LEN_1 + LARGE_FILE_HEADER_SIZE +
  1419. LARGE_FILE_TRAILER_SIZE;
  1420. if (bytes != slen) {
  1421. fprintf(stderr,
  1422. "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
  1423. slen, bytes);
  1424. fprintf(stderr,
  1425. "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
  1426. PR_GetError(), PR_GetOSError());
  1427. failed_already=1;
  1428. }
  1429. /*
  1430. * case 3: partial small file at non-zero offset, with header
  1431. */
  1432. sfd.fd = local_small_file_fd;
  1433. sfd.file_offset = SMALL_FILE_OFFSET_1;
  1434. sfd.file_nbytes = SMALL_FILE_LEN_1;
  1435. sfd.header = small_file_header;
  1436. sfd.hlen = SMALL_FILE_HEADER_SIZE;
  1437. sfd.trailer = NULL;
  1438. sfd.tlen = 0;
  1439. bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
  1440. PR_INTERVAL_NO_TIMEOUT);
  1441. slen = SMALL_FILE_LEN_1 + SMALL_FILE_HEADER_SIZE;
  1442. if (bytes != slen) {
  1443. fprintf(stderr,
  1444. "socket: Error - 3. PR_SendFile send_size = %d, bytes sent = %d\n",
  1445. slen, bytes);
  1446. fprintf(stderr,
  1447. "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
  1448. PR_GetError(), PR_GetOSError());
  1449. failed_already=1;
  1450. }
  1451. /*
  1452. * case 4: partial small file at non-zero offset, with trailer
  1453. */
  1454. sfd.fd = local_small_file_fd;
  1455. sfd.file_offset = SMALL_FILE_OFFSET_2;
  1456. sfd.file_nbytes = SMALL_FILE_LEN_2;
  1457. sfd.header = NULL;
  1458. sfd.hlen = 0;
  1459. sfd.trailer = small_file_trailer;
  1460. sfd.tlen = SMALL_FILE_TRAILER_SIZE;
  1461. bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
  1462. PR_INTERVAL_NO_TIMEOUT);
  1463. slen = SMALL_FILE_LEN_2 + SMALL_FILE_TRAILER_SIZE;
  1464. if (bytes != slen) {
  1465. fprintf(stderr,
  1466. "socket: Error - 4. PR_SendFile send_size = %d, bytes sent = %d\n",
  1467. slen, bytes);
  1468. fprintf(stderr,
  1469. "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
  1470. PR_GetError(), PR_GetOSError());
  1471. failed_already=1;
  1472. }
  1473. /*
  1474. * case 5: partial large file at non-zero offset, file with header
  1475. */
  1476. sfd.fd = local_large_file_fd;
  1477. sfd.file_offset = LARGE_FILE_OFFSET_2;
  1478. sfd.file_nbytes = LARGE_FILE_LEN_2;
  1479. sfd.header = large_file_header;
  1480. sfd.hlen = LARGE_FILE_HEADER_SIZE;
  1481. sfd.trailer = NULL;
  1482. sfd.tlen = 0;
  1483. bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
  1484. PR_INTERVAL_NO_TIMEOUT);
  1485. slen = LARGE_FILE_LEN_2 + LARGE_FILE_HEADER_SIZE;
  1486. if (bytes != slen) {
  1487. fprintf(stderr,
  1488. "socket: Error - 5. PR_SendFile send_size = %d, bytes sent = %d\n",
  1489. slen, bytes);
  1490. fprintf(stderr,
  1491. "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
  1492. PR_GetError(), PR_GetOSError());
  1493. failed_already=1;
  1494. }
  1495. /*
  1496. * case 6: partial small file from non-zero offset till end of file, with header
  1497. */
  1498. sfd.fd = local_small_file_fd;
  1499. sfd.file_offset = SMALL_FILE_OFFSET_3;
  1500. sfd.file_nbytes = 0; /* data from offset to end-of-file */
  1501. sfd.header = small_file_header;
  1502. sfd.hlen = SMALL_FILE_HEADER_SIZE;
  1503. sfd.trailer = NULL;
  1504. sfd.tlen = 0;
  1505. bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
  1506. PR_INTERVAL_NO_TIMEOUT);
  1507. slen = SMALL_FILE_LEN_3 + SMALL_FILE_HEADER_SIZE;
  1508. if (bytes != slen) {
  1509. fprintf(stderr,
  1510. "socket: Error - 6. PR_SendFile send_size = %d, bytes sent = %d\n",
  1511. slen, bytes);
  1512. fprintf(stderr,
  1513. "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
  1514. PR_GetError(), PR_GetOSError());
  1515. failed_already=1;
  1516. }
  1517. /*
  1518. * case 7: partial large file at non-zero offset till end-of-file, with header
  1519. */
  1520. sfd.fd = local_large_file_fd;
  1521. sfd.file_offset = LARGE_FILE_OFFSET_3;
  1522. sfd.file_nbytes = 0; /* data until end-of-file */
  1523. sfd.header = large_file_header;
  1524. sfd.hlen = LARGE_FILE_HEADER_SIZE;
  1525. sfd.trailer = NULL;
  1526. sfd.tlen = 0;
  1527. bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_KEEP_OPEN,
  1528. PR_INTERVAL_NO_TIMEOUT);
  1529. slen = LARGE_FILE_LEN_3 + LARGE_FILE_HEADER_SIZE;
  1530. if (bytes != slen) {
  1531. fprintf(stderr,
  1532. "socket: Error - 7. PR_SendFile send_size = %d, bytes sent = %d\n",
  1533. slen, bytes);
  1534. fprintf(stderr,
  1535. "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
  1536. PR_GetError(), PR_GetOSError());
  1537. failed_already=1;
  1538. }
  1539. /*
  1540. * case 8: partial large file at non-zero page-aligned offset,
  1541. * with header and trailer
  1542. */
  1543. sfd.fd = local_large_file_fd;
  1544. sfd.file_offset = LARGE_FILE_OFFSET_4;
  1545. sfd.file_nbytes = LARGE_FILE_LEN_4;
  1546. sfd.header = large_file_header;
  1547. sfd.hlen = LARGE_FILE_HEADER_SIZE;
  1548. sfd.trailer = large_file_trailer;
  1549. sfd.tlen = LARGE_FILE_TRAILER_SIZE;
  1550. bytes = PR_SendFile(sockfd, &sfd, PR_TRANSMITFILE_CLOSE_SOCKET,
  1551. PR_INTERVAL_NO_TIMEOUT);
  1552. slen = LARGE_FILE_LEN_4 + LARGE_FILE_HEADER_SIZE +
  1553. LARGE_FILE_TRAILER_SIZE;
  1554. if (bytes != slen) {
  1555. fprintf(stderr,
  1556. "socket: Error - 2. PR_SendFile send_size = %d, bytes sent = %d\n",
  1557. slen, bytes);
  1558. fprintf(stderr,
  1559. "prsocket_test: PR_SendFile failed: (%ld, %ld)\n",
  1560. PR_GetError(), PR_GetOSError());
  1561. failed_already=1;
  1562. }
  1563. done:
  1564. if (local_small_file_fd != NULL) {
  1565. PR_Close(local_small_file_fd);
  1566. }
  1567. if (local_large_file_fd != NULL) {
  1568. PR_Close(local_large_file_fd);
  1569. }
  1570. }
  1571. /*
  1572. * TransmitFile Server
  1573. * Server Thread
  1574. * Bind an address to a socket and listen for incoming connections
  1575. * Create worker threads to service clients
  1576. */
  1577. static void
  1578. TransmitFile_Server(void *arg)
  1579. {
  1580. PRThread **t = NULL; /* an array of PRThread pointers */
  1581. Server_Param *sp = (Server_Param *) arg;
  1582. Serve_Client_Param *scp;
  1583. PRFileDesc *sockfd = NULL, *newsockfd;
  1584. PRNetAddr netaddr;
  1585. PRInt32 i;
  1586. t = (PRThread**)PR_MALLOC(num_transmitfile_clients * sizeof(PRThread *));
  1587. if (t == NULL) {
  1588. fprintf(stderr, "prsocket_test: run out of memory\n");
  1589. failed_already=1;
  1590. goto exit;
  1591. }
  1592. /*
  1593. * Create a tcp socket
  1594. */
  1595. if ((sockfd = PR_OpenTCPSocket(PR_AF_INET)) == NULL) {
  1596. fprintf(stderr,"prsocket_test: PR_OpenTCPSocket failed\n");
  1597. failed_already=1;
  1598. goto exit;
  1599. }
  1600. memset(&netaddr, 0, sizeof(netaddr));
  1601. netaddr.inet.family = PR_AF_INET;
  1602. netaddr.inet.port = PR_htons(TCP_SERVER_PORT);
  1603. netaddr.inet.ip = PR_htonl(PR_INADDR_ANY);
  1604. /*
  1605. * try a few times to bind server's address, if addresses are in
  1606. * use
  1607. */
  1608. i = 0;
  1609. while (PR_Bind(sockfd, &netaddr) < 0) {
  1610. if (PR_GetError() == PR_ADDRESS_IN_USE_ERROR) {
  1611. netaddr.inet.port += 2;
  1612. if (i++ < SERVER_MAX_BIND_COUNT) {
  1613. continue;
  1614. }
  1615. }
  1616. fprintf(stderr,"prsocket_test: ERROR - PR_Bind failed\n");
  1617. failed_already=1;
  1618. perror("PR_Bind");
  1619. goto exit;
  1620. }
  1621. if (PR_Listen(sockfd, 32) < 0) {
  1622. fprintf(stderr,"prsocket_test: ERROR - PR_Listen failed\n");
  1623. failed_already=1;
  1624. goto exit;
  1625. }
  1626. if (PR_GetSockName(sockfd, &netaddr) < 0) {
  1627. fprintf(stderr,
  1628. "prsocket_test: ERROR - PR_GetSockName failed\n");
  1629. failed_already=1;
  1630. goto exit;
  1631. }
  1632. DPRINTF(("TCP_Server: PR_BIND netaddr.inet.ip = 0x%lx, netaddr.inet.port = %d\n",
  1633. netaddr.inet.ip, netaddr.inet.port));
  1634. tcp_server_addr.inet.family = netaddr.inet.family;
  1635. tcp_server_addr.inet.port = netaddr.inet.port;
  1636. tcp_server_addr.inet.ip = netaddr.inet.ip;
  1637. /*
  1638. * Wake up parent thread because server address is bound and made
  1639. * available in the global variable 'tcp_server_addr'
  1640. */
  1641. PR_PostSem(sp->addr_sem);
  1642. for (i = 0; i < num_transmitfile_clients ; i++) {
  1643. /* test both null and non-null 'addr' argument to PR_Accept */
  1644. PRNetAddr *addrp = (i%2 ? &netaddr: NULL);
  1645. if ((newsockfd = PR_Accept(sockfd, addrp,
  1646. PR_INTERVAL_NO_TIMEOUT)) == NULL) {
  1647. fprintf(stderr,
  1648. "prsocket_test: ERROR - PR_Accept failed\n");
  1649. failed_already=1;
  1650. goto exit;
  1651. }
  1652. /* test both regular and emulated PR_SendFile */
  1653. if (i%2) {
  1654. PRFileDesc *layer = PR_CreateIOLayerStub(
  1655. emuSendFileIdentity, &emuSendFileMethods);
  1656. if (layer == NULL) {
  1657. fprintf(stderr,
  1658. "prsocket_test: ERROR - PR_CreateIOLayerStub failed\n");
  1659. failed_already=1;
  1660. goto exit;
  1661. }
  1662. if (PR_PushIOLayer(newsockfd, PR_TOP_IO_LAYER, layer)
  1663. == PR_FAILURE) {
  1664. fprintf(stderr,
  1665. "prsocket_test: ERROR - PR_PushIOLayer failed\n");
  1666. failed_already=1;
  1667. goto exit;
  1668. }
  1669. }
  1670. scp = PR_NEW(Serve_Client_Param);
  1671. if (scp == NULL) {
  1672. fprintf(stderr,"prsocket_test: PR_NEW failed\n");
  1673. failed_already=1;
  1674. goto exit;
  1675. }
  1676. /*
  1677. * Start a Serve_Client thread for each incoming connection
  1678. */
  1679. scp->sockfd = newsockfd;
  1680. scp->datalen = sp->datalen;
  1681. t[i] = PR_CreateThread(PR_USER_THREAD,
  1682. Serve_TransmitFile_Client, (void *)scp,
  1683. PR_PRIORITY_NORMAL,
  1684. PR_LOCAL_THREAD,
  1685. PR_JOINABLE_THREAD,
  1686. 0);
  1687. if (t[i] == NULL) {
  1688. fprintf(stderr,
  1689. "prsocket_test: PR_CreateThread failed\n");
  1690. failed_already=1;
  1691. goto exit;
  1692. }
  1693. DPRINTF(("TransmitFile_Server: Created Serve_TransmitFile_Client = 0x%lx\n", t));
  1694. }
  1695. /*
  1696. * Wait for all the worker threads to end, so that we know
  1697. * they are no longer using the small and large file fd's.
  1698. */
  1699. for (i = 0; i < num_transmitfile_clients; i++) {
  1700. PR_JoinThread(t[i]);
  1701. }
  1702. exit:
  1703. if (t) {
  1704. PR_DELETE(t);
  1705. }
  1706. if (sockfd) {
  1707. PR_Close(sockfd);
  1708. }
  1709. /*
  1710. * Decrement exit_counter and notify parent thread
  1711. */
  1712. PR_EnterMonitor(sp->exit_mon);
  1713. --(*sp->exit_counter);
  1714. PR_Notify(sp->exit_mon);
  1715. PR_ExitMonitor(sp->exit_mon);
  1716. DPRINTF(("TransmitFile_Server [0x%lx] exiting\n", PR_GetCurrentThread()));
  1717. }
  1718. /*
  1719. * Socket_Misc_Test - test miscellaneous functions
  1720. *
  1721. */
  1722. static PRInt32
  1723. Socket_Misc_Test(void)
  1724. {
  1725. PRIntn i, rv = 0, bytes, count, len;
  1726. PRThread *t;
  1727. PRSemaphore *server_sem;
  1728. Server_Param *sparamp;
  1729. Client_Param *cparamp;
  1730. PRMonitor *mon2;
  1731. PRInt32 datalen;
  1732. /*
  1733. * We deliberately pick a buffer size that is not a nice multiple
  1734. * of 1024.
  1735. */
  1736. #define TRANSMITFILE_BUF_SIZE (4 * 1024 - 11)
  1737. typedef struct {
  1738. char data[TRANSMITFILE_BUF_SIZE];
  1739. } file_buf;
  1740. file_buf *buf = NULL;
  1741. /*
  1742. * create file(s) to be transmitted
  1743. */
  1744. if ((PR_MkDir(TEST_DIR, 0777)) < 0) {
  1745. printf("prsocket_test failed to create dir %s\n",TEST_DIR);
  1746. failed_already=1;
  1747. return -1;
  1748. }
  1749. small_file_fd = PR_Open(SMALL_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);
  1750. if (small_file_fd == NULL) {
  1751. fprintf(stderr,"prsocket_test failed to create/open file %s\n",
  1752. SMALL_FILE_NAME);
  1753. failed_already=1;
  1754. rv = -1;
  1755. goto done;
  1756. }
  1757. buf = PR_NEW(file_buf);
  1758. if (buf == NULL) {
  1759. fprintf(stderr,"prsocket_test failed to allocate buffer\n");
  1760. failed_already=1;
  1761. rv = -1;
  1762. goto done;
  1763. }
  1764. /*
  1765. * fill in random data
  1766. */
  1767. for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
  1768. buf->data[i] = i;
  1769. }
  1770. count = 0;
  1771. do {
  1772. len = (SMALL_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
  1773. TRANSMITFILE_BUF_SIZE : (SMALL_FILE_SIZE - count);
  1774. bytes = PR_Write(small_file_fd, buf->data, len);
  1775. if (bytes <= 0) {
  1776. fprintf(stderr,
  1777. "prsocket_test failed to write to file %s\n",
  1778. SMALL_FILE_NAME);
  1779. failed_already=1;
  1780. rv = -1;
  1781. goto done;
  1782. }
  1783. count += bytes;
  1784. } while (count < SMALL_FILE_SIZE);
  1785. #ifdef XP_UNIX
  1786. /*
  1787. * map the small file; used in checking for data corruption
  1788. */
  1789. small_file_addr = mmap(0, SMALL_FILE_SIZE, PROT_READ,
  1790. MAP_SHARED, small_file_fd->secret->md.osfd, 0);
  1791. if (small_file_addr == (void *) -1) {
  1792. fprintf(stderr,"prsocket_test failed to mmap file %s\n",
  1793. SMALL_FILE_NAME);
  1794. failed_already=1;
  1795. rv = -1;
  1796. goto done;
  1797. }
  1798. #endif
  1799. /*
  1800. * header for small file
  1801. */
  1802. small_file_header = PR_MALLOC(SMALL_FILE_HEADER_SIZE);
  1803. if (small_file_header == NULL) {
  1804. fprintf(stderr,"prsocket_test failed to malloc header file\n");
  1805. failed_already=1;
  1806. rv = -1;
  1807. goto done;
  1808. }
  1809. memset(small_file_header, (int) PR_IntervalNow(),
  1810. SMALL_FILE_HEADER_SIZE);
  1811. /*
  1812. * trailer for small file
  1813. */
  1814. small_file_trailer = PR_MALLOC(SMALL_FILE_TRAILER_SIZE);
  1815. if (small_file_trailer == NULL) {
  1816. fprintf(stderr,"prsocket_test failed to malloc header trailer\n");
  1817. failed_already=1;
  1818. rv = -1;
  1819. goto done;
  1820. }
  1821. memset(small_file_trailer, (int) PR_IntervalNow(),
  1822. SMALL_FILE_TRAILER_SIZE);
  1823. /*
  1824. * setup large file
  1825. */
  1826. large_file_fd = PR_Open(LARGE_FILE_NAME, PR_RDWR | PR_CREATE_FILE,0777);
  1827. if (large_file_fd == NULL) {
  1828. fprintf(stderr,"prsocket_test failed to create/open file %s\n",
  1829. LARGE_FILE_NAME);
  1830. failed_already=1;
  1831. rv = -1;
  1832. goto done;
  1833. }
  1834. /*
  1835. * fill in random data
  1836. */
  1837. for (i = 0; i < TRANSMITFILE_BUF_SIZE; i++) {
  1838. buf->data[i] = i;
  1839. }
  1840. count = 0;
  1841. do {
  1842. len = (LARGE_FILE_SIZE - count) > TRANSMITFILE_BUF_SIZE ?
  1843. TRANSMITFILE_BUF_SIZE : (LARGE_FILE_SIZE - count);
  1844. bytes = PR_Write(large_file_fd, buf->data, len);
  1845. if (bytes <= 0) {
  1846. fprintf(stderr,
  1847. "prsocket_test failed to write to file %s: (%ld, %ld)\n",
  1848. LARGE_FILE_NAME,
  1849. PR_GetError(), PR_GetOSError());
  1850. failed_already=1;
  1851. rv = -1;
  1852. goto done;
  1853. }
  1854. count += bytes;
  1855. } while (count < LARGE_FILE_SIZE);
  1856. #if defined(XP_UNIX)
  1857. /*
  1858. * map the large file; used in checking for data corruption
  1859. */
  1860. large_file_addr = mmap(0, LARGE_FILE_SIZE, PROT_READ,
  1861. MAP_SHARED, large_file_fd->secret->md.osfd, 0);
  1862. if (large_file_addr == (void *) -1) {
  1863. fprintf(stderr,"prsocket_test failed to mmap file %s\n",
  1864. LARGE_FILE_NAME);
  1865. failed_already=1;
  1866. rv = -1;
  1867. goto done;
  1868. }
  1869. #endif
  1870. /*
  1871. * header for large file
  1872. */
  1873. large_file_header = PR_MALLOC(LARGE_FILE_HEADER_SIZE);
  1874. if (large_file_header == NULL) {
  1875. fprintf(stderr,"prsocket_test failed to malloc header file\n");
  1876. failed_already=1;
  1877. rv = -1;
  1878. goto done;
  1879. }
  1880. memset(large_file_header, (int) PR_IntervalNow(),
  1881. LARGE_FILE_HEADER_SIZE);
  1882. /*
  1883. * trailer for large file
  1884. */
  1885. large_file_trailer = PR_MALLOC(LARGE_FILE_TRAILER_SIZE);
  1886. if (large_file_trailer == NULL) {
  1887. fprintf(stderr,"prsocket_test failed to malloc header trailer\n");
  1888. failed_already=1;
  1889. rv = -1;
  1890. goto done;
  1891. }
  1892. memset(large_file_trailer, (int) PR_IntervalNow(),
  1893. LARGE_FILE_TRAILER_SIZE);
  1894. datalen = tcp_mesg_size;
  1895. thread_count = 0;
  1896. /*
  1897. * start the server thread
  1898. */
  1899. sparamp = PR_NEW(Server_Param);
  1900. if (sparamp == NULL) {
  1901. fprintf(stderr,"prsocket_test: PR_NEW failed\n");
  1902. failed_already=1;
  1903. rv = -1;
  1904. goto done;
  1905. }
  1906. server_sem = PR_NewSem(0);
  1907. if (server_sem == NULL) {
  1908. fprintf(stderr,"prsocket_test: PR_NewSem failed\n");
  1909. failed_already=1;
  1910. rv = -1;
  1911. goto done;
  1912. }
  1913. mon2 = PR_NewMonitor();
  1914. if (mon2 == NULL) {
  1915. fprintf(stderr,"prsocket_test: PR_NewMonitor failed\n");
  1916. failed_already=1;
  1917. rv = -1;
  1918. goto done;
  1919. }
  1920. PR_EnterMonitor(mon2);
  1921. sparamp->addr_sem = server_sem;
  1922. sparamp->exit_mon = mon2;
  1923. sparamp->exit_counter = &thread_count;
  1924. sparamp->datalen = datalen;
  1925. t = PR_CreateThread(PR_USER_THREAD,
  1926. TransmitFile_Server, (void *)sparamp,
  1927. PR_PRIORITY_NORMAL,
  1928. PR_LOCAL_THREAD,
  1929. PR_UNJOINABLE_THREAD,
  1930. 0);
  1931. if (t == NULL) {
  1932. fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
  1933. failed_already=1;
  1934. rv = -1;
  1935. goto done;
  1936. }
  1937. DPRINTF(("Created TCP server = 0x%x\n", t));
  1938. thread_count++;
  1939. /*
  1940. * wait till the server address is setup
  1941. */
  1942. PR_WaitSem(server_sem);
  1943. /*
  1944. * Now start a bunch of client threads
  1945. */
  1946. cparamp = PR_NEW(Client_Param);
  1947. if (cparamp == NULL) {
  1948. fprintf(stderr,"prsocket_test: PR_NEW failed\n");
  1949. failed_already=1;
  1950. rv = -1;
  1951. goto done;
  1952. }
  1953. cparamp->server_addr = tcp_server_addr;
  1954. cparamp->server_addr.inet.ip = PR_htonl(PR_INADDR_LOOPBACK);
  1955. cparamp->exit_mon = mon2;
  1956. cparamp->exit_counter = &thread_count;
  1957. cparamp->datalen = datalen;
  1958. for (i = 0; i < num_transmitfile_clients; i++) {
  1959. t = create_new_thread(PR_USER_THREAD,
  1960. TransmitFile_Client, (void *) cparamp,
  1961. PR_PRIORITY_NORMAL,
  1962. PR_LOCAL_THREAD,
  1963. PR_UNJOINABLE_THREAD,
  1964. 0, i);
  1965. if (t == NULL) {
  1966. fprintf(stderr,"prsocket_test: PR_CreateThread failed\n");
  1967. rv = -1;
  1968. failed_already=1;
  1969. goto done;
  1970. }
  1971. DPRINTF(("Created TransmitFile client = 0x%lx\n", t));
  1972. thread_count++;
  1973. }
  1974. /* Wait for server and client threads to exit */
  1975. while (thread_count) {
  1976. PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT);
  1977. DPRINTF(("Socket_Misc_Test - thread_count = %d\n", thread_count));
  1978. }
  1979. PR_ExitMonitor(mon2);
  1980. done:
  1981. if (buf) {
  1982. PR_DELETE(buf);
  1983. }
  1984. #if defined(XP_UNIX)
  1985. munmap((char*)small_file_addr, SMALL_FILE_SIZE);
  1986. munmap((char*)large_file_addr, LARGE_FILE_SIZE);
  1987. #endif
  1988. PR_Close(small_file_fd);
  1989. PR_Close(large_file_fd);
  1990. if ((PR_Delete(SMALL_FILE_NAME)) == PR_FAILURE) {
  1991. fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
  1992. SMALL_FILE_NAME);
  1993. failed_already=1;
  1994. }
  1995. if ((PR_Delete(LARGE_FILE_NAME)) == PR_FAILURE) {
  1996. fprintf(stderr,"prsocket_test: failed to unlink file %s\n",
  1997. LARGE_FILE_NAME);
  1998. failed_already=1;
  1999. }
  2000. if ((PR_RmDir(TEST_DIR)) == PR_FAILURE) {
  2001. fprintf(stderr,"prsocket_test failed to rmdir %s: (%ld, %ld)\n",
  2002. TEST_DIR, PR_GetError(), PR_GetOSError());
  2003. failed_already=1;
  2004. }
  2005. printf("%-29s%s","Socket_Misc_Test",":");
  2006. printf("%2d Server %2d Clients\n",1, num_transmitfile_clients);
  2007. printf("%30s Sizes of Transmitted Files - %4d KB, %2d MB \n",":",
  2008. SMALL_FILE_SIZE/1024, LARGE_FILE_SIZE/(1024 * 1024));
  2009. return rv;
  2010. }
  2011. /************************************************************************/
  2012. /*
  2013. * Test Socket NSPR APIs
  2014. */
  2015. int main(int argc, char **argv)
  2016. {
  2017. /*
  2018. * -d debug mode
  2019. */
  2020. PLOptStatus os;
  2021. PLOptState *opt = PL_CreateOptState(argc, argv, "d");
  2022. while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
  2023. {
  2024. if (PL_OPT_BAD == os) {
  2025. continue;
  2026. }
  2027. switch (opt->option)
  2028. {
  2029. case 'd': /* debug mode */
  2030. _debug_on = 1;
  2031. break;
  2032. default:
  2033. break;
  2034. }
  2035. }
  2036. PL_DestroyOptState(opt);
  2037. PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
  2038. PR_STDIO_INIT();
  2039. PR_SetConcurrency(4);
  2040. emuSendFileIdentity = PR_GetUniqueIdentity("Emulated SendFile");
  2041. emuSendFileMethods = *PR_GetDefaultIOMethods();
  2042. emuSendFileMethods.transmitfile = emu_TransmitFile;
  2043. emuSendFileMethods.sendfile = emu_SendFile;
  2044. /*
  2045. * run client-server test with TCP, Ipv4-Ipv4
  2046. */
  2047. printf("TCP Client/Server Test - IPv4/Ipv4\n");
  2048. if (TCP_Socket_Client_Server_Test() < 0) {
  2049. printf("TCP_Socket_Client_Server_Test failed\n");
  2050. goto done;
  2051. } else {
  2052. printf("TCP_Socket_Client_Server_Test Passed\n");
  2053. }
  2054. /*
  2055. * client-server test, Ipv6-Ipv4
  2056. */
  2057. client_domain = PR_AF_INET6;
  2058. printf("TCP Client/Server Test - IPv6/Ipv4\n");
  2059. if (TCP_Socket_Client_Server_Test() < 0) {
  2060. printf("TCP_Socket_Client_Server_Test failed\n");
  2061. goto done;
  2062. } else {
  2063. printf("TCP_Socket_Client_Server_Test Passed\n");
  2064. }
  2065. /*
  2066. * client-server test, Ipv4-Ipv6
  2067. */
  2068. client_domain = PR_AF_INET;
  2069. server_domain = PR_AF_INET6;
  2070. printf("TCP Client/Server Test - IPv4/Ipv6\n");
  2071. if (TCP_Socket_Client_Server_Test() < 0) {
  2072. printf("TCP_Socket_Client_Server_Test failed\n");
  2073. goto done;
  2074. } else {
  2075. printf("TCP_Socket_Client_Server_Test Passed\n");
  2076. }
  2077. /*
  2078. * client-server test, Ipv6-Ipv6
  2079. */
  2080. client_domain = PR_AF_INET6;
  2081. server_domain = PR_AF_INET6;
  2082. printf("TCP Client/Server Test - IPv6/Ipv6\n");
  2083. if (TCP_Socket_Client_Server_Test() < 0) {
  2084. printf("TCP_Socket_Client_Server_Test failed\n");
  2085. goto done;
  2086. } else {
  2087. printf("TCP_Socket_Client_Server_Test Passed\n");
  2088. }
  2089. test_cancelio = 0;
  2090. /*
  2091. * Misc socket tests - including transmitfile, etc.
  2092. */
  2093. /* File transmission test can not be done in Symbian OS because of
  2094. * large file's size and the incomplete mmap() implementation. */
  2095. #if !defined(WIN16)
  2096. /*
  2097. ** The 'transmit file' test does not run because
  2098. ** transmit file is not implemented in NSPR yet.
  2099. **
  2100. */
  2101. if (Socket_Misc_Test() < 0) {
  2102. printf("Socket_Misc_Test failed\n");
  2103. failed_already=1;
  2104. goto done;
  2105. } else {
  2106. printf("Socket_Misc_Test passed\n");
  2107. }
  2108. /*
  2109. * run client-server test with TCP again to test
  2110. * recycling used sockets from PR_TransmitFile().
  2111. */
  2112. if (TCP_Socket_Client_Server_Test() < 0) {
  2113. printf("TCP_Socket_Client_Server_Test failed\n");
  2114. goto done;
  2115. } else {
  2116. printf("TCP_Socket_Client_Server_Test Passed\n");
  2117. }
  2118. #endif
  2119. done:
  2120. PR_Cleanup();
  2121. if (failed_already) {
  2122. return 1;
  2123. }
  2124. else {
  2125. return 0;
  2126. }
  2127. }