Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
6 #include <prio.h>
7 #include <prprf.h>
8 #include <prinit.h>
9 #include <prnetdb.h>
10 #include <prinrval.h>
11 #include <prthread.h>
13 #include <plerror.h>
15 #include <stdlib.h>
17 #define DEFAULT_PORT 12273
18 #define GET "GET / HTTP/1.0\n\n"
19 static PRFileDesc *std_out, *err_out;
20 static PRIntervalTime write_dally, accept_timeout;
22 static PRStatus PrintAddress(const PRNetAddr* address)
23 {
24 char buffer[100];
25 PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
26 if (PR_FAILURE == rv) PL_FPrintError(err_out, "PR_NetAddrToString");
27 else PR_fprintf(
28 std_out, "Accepted connection from (0x%p)%s:%d\n",
29 address, buffer, address->inet.port);
30 return rv;
31 } /* PrintAddress */
33 static void ConnectingThread(void *arg)
34 {
35 PRInt32 nbytes;
36 #ifdef SYMBIAN
37 char buf[256];
38 #else
39 char buf[1024];
40 #endif
41 PRFileDesc *sock;
42 PRNetAddr peer_addr, *addr;
44 addr = (PRNetAddr*)arg;
46 sock = PR_NewTCPSocket();
47 if (sock == NULL)
48 {
49 PL_FPrintError(err_out, "PR_NewTCPSocket (client) failed");
50 PR_ProcessExit(1);
51 }
53 if (PR_Connect(sock, addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE)
54 {
55 PL_FPrintError(err_out, "PR_Connect (client) failed");
56 PR_ProcessExit(1);
57 }
58 if (PR_GetPeerName(sock, &peer_addr) == PR_FAILURE)
59 {
60 PL_FPrintError(err_out, "PR_GetPeerName (client) failed");
61 PR_ProcessExit(1);
62 }
64 /*
65 ** Then wait between the connection coming up and sending the expected
66 ** data. At some point in time, the server should fail due to a timeou
67 ** on the AcceptRead() operation, which according to the document is
68 ** only due to the read() portion.
69 */
70 PR_Sleep(write_dally);
72 nbytes = PR_Send(sock, GET, sizeof(GET), 0, PR_INTERVAL_NO_TIMEOUT);
73 if (nbytes == -1) PL_FPrintError(err_out, "PR_Send (client) failed");
75 nbytes = PR_Recv(sock, buf, sizeof(buf), 0, PR_INTERVAL_NO_TIMEOUT);
76 if (nbytes == -1) PL_FPrintError(err_out, "PR_Recv (client) failed");
77 else
78 {
79 PR_fprintf(std_out, "PR_Recv (client) succeeded: %d bytes\n", nbytes);
80 buf[sizeof(buf) - 1] = '\0';
81 PR_fprintf(std_out, "%s\n", buf);
82 }
84 if (PR_FAILURE == PR_Shutdown(sock, PR_SHUTDOWN_BOTH))
85 PL_FPrintError(err_out, "PR_Shutdown (client) failed");
87 if (PR_FAILURE == PR_Close(sock))
88 PL_FPrintError(err_out, "PR_Close (client) failed");
90 return;
91 } /* ConnectingThread */
93 #define BUF_SIZE 117
94 static void AcceptingThread(void *arg)
95 {
96 PRStatus rv;
97 PRInt32 bytes;
98 PRSize buf_size = BUF_SIZE;
99 PRUint8 buf[BUF_SIZE + (2 * sizeof(PRNetAddr)) + 32];
100 PRNetAddr *accept_addr, *listen_addr = (PRNetAddr*)arg;
101 PRFileDesc *accept_sock, *listen_sock = PR_NewTCPSocket();
102 PRSocketOptionData sock_opt;
104 if (NULL == listen_sock)
105 {
106 PL_FPrintError(err_out, "PR_NewTCPSocket (server) failed");
107 PR_ProcessExit(1);
108 }
109 sock_opt.option = PR_SockOpt_Reuseaddr;
110 sock_opt.value.reuse_addr = PR_TRUE;
111 rv = PR_SetSocketOption(listen_sock, &sock_opt);
112 if (PR_FAILURE == rv)
113 {
114 PL_FPrintError(err_out, "PR_SetSocketOption (server) failed");
115 PR_ProcessExit(1);
116 }
117 rv = PR_Bind(listen_sock, listen_addr);
118 if (PR_FAILURE == rv)
119 {
120 PL_FPrintError(err_out, "PR_Bind (server) failed");
121 PR_ProcessExit(1);
122 }
123 rv = PR_Listen(listen_sock, 10);
124 if (PR_FAILURE == rv)
125 {
126 PL_FPrintError(err_out, "PR_Listen (server) failed");
127 PR_ProcessExit(1);
128 }
129 bytes = PR_AcceptRead(
130 listen_sock, &accept_sock, &accept_addr, buf, buf_size, accept_timeout);
132 if (-1 == bytes) PL_FPrintError(err_out, "PR_AcceptRead (server) failed");
133 else
134 {
135 PrintAddress(accept_addr);
136 PR_fprintf(
137 std_out, "(Server) read [0x%p..0x%p) %s\n",
138 buf, &buf[BUF_SIZE], buf);
139 bytes = PR_Write(accept_sock, buf, bytes);
140 rv = PR_Shutdown(accept_sock, PR_SHUTDOWN_BOTH);
141 if (PR_FAILURE == rv)
142 PL_FPrintError(err_out, "PR_Shutdown (server) failed");
143 }
145 if (-1 != bytes)
146 {
147 rv = PR_Close(accept_sock);
148 if (PR_FAILURE == rv)
149 PL_FPrintError(err_out, "PR_Close (server) failed");
150 }
152 rv = PR_Close(listen_sock);
153 if (PR_FAILURE == rv)
154 PL_FPrintError(err_out, "PR_Close (server) failed");
155 } /* AcceptingThread */
157 int main(int argc, char **argv)
158 {
159 PRHostEnt he;
160 PRStatus status;
161 PRIntn next_index;
162 PRUint16 port_number;
163 char netdb_buf[PR_NETDB_BUF_SIZE];
164 PRNetAddr client_addr, server_addr;
165 PRThread *client_thread, *server_thread;
166 PRIntervalTime delta = PR_MillisecondsToInterval(500);
168 err_out = PR_STDERR;
169 std_out = PR_STDOUT;
170 accept_timeout = PR_SecondsToInterval(2);
172 if (argc != 2 && argc != 3) port_number = DEFAULT_PORT;
173 else port_number = (PRUint16)atoi(argv[(argc == 2) ? 1 : 2]);
175 status = PR_InitializeNetAddr(PR_IpAddrAny, port_number, &server_addr);
176 if (PR_SUCCESS != status)
177 {
178 PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
179 PR_ProcessExit(1);
180 }
181 if (argc < 3)
182 {
183 status = PR_InitializeNetAddr(
184 PR_IpAddrLoopback, port_number, &client_addr);
185 if (PR_SUCCESS != status)
186 {
187 PL_FPrintError(err_out, "PR_InitializeNetAddr failed");
188 PR_ProcessExit(1);
189 }
190 }
191 else
192 {
193 status = PR_GetHostByName(
194 argv[1], netdb_buf, sizeof(netdb_buf), &he);
195 if (status == PR_FAILURE)
196 {
197 PL_FPrintError(err_out, "PR_GetHostByName failed");
198 PR_ProcessExit(1);
199 }
200 next_index = PR_EnumerateHostEnt(0, &he, port_number, &client_addr);
201 if (next_index == -1)
202 {
203 PL_FPrintError(err_out, "PR_EnumerateHostEnt failed");
204 PR_ProcessExit(1);
205 }
206 }
208 for (
209 write_dally = 0;
210 write_dally < accept_timeout + (2 * delta);
211 write_dally += delta)
212 {
213 PR_fprintf(
214 std_out, "Testing w/ write_dally = %d msec\n",
215 PR_IntervalToMilliseconds(write_dally));
216 server_thread = PR_CreateThread(
217 PR_USER_THREAD, AcceptingThread, &server_addr,
218 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
219 if (server_thread == NULL)
220 {
221 PL_FPrintError(err_out, "PR_CreateThread (server) failed");
222 PR_ProcessExit(1);
223 }
225 PR_Sleep(delta); /* let the server pot thicken */
227 client_thread = PR_CreateThread(
228 PR_USER_THREAD, ConnectingThread, &client_addr,
229 PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
230 if (client_thread == NULL)
231 {
232 PL_FPrintError(err_out, "PR_CreateThread (client) failed");
233 PR_ProcessExit(1);
234 }
236 if (PR_JoinThread(client_thread) == PR_FAILURE)
237 PL_FPrintError(err_out, "PR_JoinThread (client) failed");
239 if (PR_JoinThread(server_thread) == PR_FAILURE)
240 PL_FPrintError(err_out, "PR_JoinThread (server) failed");
241 }
243 return 0;
244 }