Skip to content

Commit e169733

Browse files
committed
Update TCP proxy to address Coverity errors
Coverity seems to have some problems with the loop(s) copying data from one socket to another, in that it assume that eventually an integer overflow will occur. It's not obvious why this should be flagged, but this seems likely to be a false positive. This commit avoids the integer issue by using a simple pointer + count mechanism. The socket copy code has been placed in a separate function - before it was duplicated. Minor fixes have been made to error reporting around the connection code.
1 parent d924440 commit e169733

File tree

1 file changed

+74
-83
lines changed

1 file changed

+74
-83
lines changed

tools/devel/tcp_proxy/main.c

+74-83
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ int g_loc_io_count = 0; // bytes read from local port
4343
int g_rem_io_count = 0; // bytes read from remote port
4444

4545
static int g_terminated = 0;
46-
static char g_buf[1024 * 32];
47-
4846

4947
typedef unsigned short tui16;
5048

@@ -67,6 +65,67 @@ g_tcp_socket_ok(int sck)
6765
return 0;
6866
}
6967

68+
/*****************************************************************************/
69+
static int
70+
copy_sck_to_sck(int from_sck, int to_sck, int hexdump, int local)
71+
{
72+
char buff[1024 * 32];
73+
int rv = -1;
74+
75+
int count = g_tcp_recv(from_sck, buff, sizeof(buff), 0);
76+
if (count > 0 && count <= (int)sizeof(buff))
77+
{
78+
rv = count; // Assume we'll return the amount of data copied
79+
if (local)
80+
{
81+
g_loc_io_count += count;
82+
if (hexdump)
83+
{
84+
LOG_HEXDUMP(LOG_LEVEL_INFO, "from local:", buff, count);
85+
}
86+
}
87+
else
88+
{
89+
g_rem_io_count += count;
90+
if (hexdump)
91+
{
92+
LOG_HEXDUMP(LOG_LEVEL_INFO, "from remote:", buff, count);
93+
}
94+
}
95+
96+
97+
LOG(LOG_LEVEL_DEBUG, "local_io_count: %d\tremote_io_count: %d",
98+
g_loc_io_count, g_rem_io_count);
99+
100+
const char *p = buff;
101+
while ((count > 0) && (!g_terminated))
102+
{
103+
int error = g_tcp_send(to_sck, p, count, 0);
104+
105+
if (error > 0 && error <= count)
106+
{
107+
// We wrote some data
108+
count -= error;
109+
p += error;
110+
}
111+
else if ((error == -1) && g_tcp_last_error_would_block(to_sck))
112+
{
113+
if (g_tcp_can_send(to_sck, 1000))
114+
{
115+
g_tcp_socket_ok(to_sck);
116+
}
117+
}
118+
else
119+
{
120+
count = 0; // Terminate loop
121+
rv = -1; // tell user
122+
}
123+
}
124+
}
125+
126+
return rv;
127+
}
128+
70129
/*****************************************************************************/
71130
static int
72131
main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
@@ -76,7 +135,6 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
76135
int con_sck = -1;
77136
int sel;
78137
int count;
79-
int sent;
80138
int error;
81139
int i;
82140
int acc_to_con = 0;
@@ -165,9 +223,8 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
165223
error = 0;
166224
i = 0;
167225

168-
while (!(g_tcp_can_send(con_sck, 100) && g_tcp_socket_ok(con_sck))
169-
&& (!g_terminated)
170-
&& (i < 100))
226+
while (!g_terminated && i < 100 &&
227+
!g_tcp_can_send(con_sck, 100))
171228
{
172229
g_sleep(100);
173230
i++;
@@ -178,8 +235,7 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
178235
LOG(LOG_LEVEL_ERROR, "timeout connecting");
179236
error = 1;
180237
}
181-
182-
if (g_terminated)
238+
else if (!g_tcp_socket_ok(con_sck))
183239
{
184240
error = 1;
185241
}
@@ -191,7 +247,7 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
191247
}
192248
}
193249

194-
while ((!g_terminated) && (error == 0))
250+
while (!g_terminated)
195251
{
196252
sel = g_tcp_select(con_sck, acc_sck);
197253

@@ -204,87 +260,22 @@ main_loop(char *local_port, char *remote_ip, char *remote_port, int hexdump)
204260
if (sel & 1)
205261
{
206262
// can read from con_sck w/o blocking
207-
count = g_tcp_recv(con_sck, g_buf, 1024 * 16, 0);
208-
error = count < 1;
209-
210-
if (error == 0)
263+
count = copy_sck_to_sck(con_sck, acc_sck, hexdump, 1);
264+
if (count < 0)
211265
{
212-
g_loc_io_count += count;
213-
con_to_acc += count;
214-
215-
if (hexdump)
216-
{
217-
LOG_HEXDUMP(LOG_LEVEL_INFO, "from remove, the socket from connect", g_buf, count);
218-
}
219-
220-
LOG(LOG_LEVEL_DEBUG, "local_io_count: %d\tremote_io_count: %d",
221-
g_loc_io_count, g_rem_io_count);
222-
sent = 0;
223-
224-
while ((sent < count) && (error == 0) && (!g_terminated))
225-
{
226-
i = g_tcp_send(acc_sck, g_buf + sent, count - sent, 0);
227-
228-
if ((i == -1) && g_tcp_last_error_would_block(acc_sck))
229-
{
230-
if (g_tcp_can_send(acc_sck, 1000))
231-
{
232-
g_tcp_socket_ok(acc_sck);
233-
}
234-
}
235-
else if (i < 1)
236-
{
237-
error = 1;
238-
}
239-
else
240-
{
241-
sent += i;
242-
}
243-
}
266+
break;
244267
}
268+
con_to_acc += count;
245269
}
246-
247270
if (sel & 2)
248271
{
249272
// can read from acc_sck w/o blocking
250-
count = g_tcp_recv(acc_sck, g_buf, 1024 * 16, 0);
251-
error = count < 1;
252-
253-
if (error == 0)
273+
count = copy_sck_to_sck(acc_sck, con_sck, hexdump, 0);
274+
if (count < 0)
254275
{
255-
g_rem_io_count += count;
256-
acc_to_con += count;
257-
258-
if (hexdump)
259-
{
260-
LOG_HEXDUMP(LOG_LEVEL_INFO, "from accepted, the socket from accept", g_buf, count);
261-
}
262-
263-
LOG(LOG_LEVEL_DEBUG, "local_io_count: %d\tremote_io_count: %d",
264-
g_loc_io_count, g_rem_io_count);
265-
sent = 0;
266-
267-
while ((sent < count) && (error == 0) && (!g_terminated))
268-
{
269-
i = g_tcp_send(con_sck, g_buf + sent, count - sent, 0);
270-
271-
if ((i == -1) && g_tcp_last_error_would_block(con_sck))
272-
{
273-
if (g_tcp_can_send(con_sck, 1000))
274-
{
275-
g_tcp_socket_ok(con_sck);
276-
}
277-
}
278-
else if (i < 1 || i > (count - sent))
279-
{
280-
error = 1;
281-
}
282-
else
283-
{
284-
sent += i;
285-
}
286-
}
287-
}
276+
break;
277+
};
278+
acc_to_con += count;
288279
}
289280
}
290281

0 commit comments

Comments
 (0)