-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.c
197 lines (192 loc) · 7.29 KB
/
proxy.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if !defined(_WIN32)
#include <sys/un.h>
#include <netinet/in.h>
#endif
#include "rasocket.h"
#include "proxy.h"
#include "usage.h"
#include "utils.h"
#include "oneTimeBuffer.h"
bool sproxy_usage(int argc, char **argv, char *usageStr, size_t usageLen)
{
return usage(argc, argv, (char *)"proxy"
,(char *)"socker proxy <proxyhostname> <proxyportnumber> <proxiedhostname> <proxiedportnumber>\n\te.g. socker proxy localhost 12900 remotehost 11900\n\tforwards any messages from client to remotehost and vice versa\n"
, usageStr, usageLen);
}
bool sproxy(int argc, char ** argv)
{
char proxyHost[ADDRESS_SIZE];
unsigned short proxyPort;
if (!getHostAndPort(argc, argv, ARG_REMOTE_HOST, ARG_PORT, proxyHost, ADDRESS_SIZE, &proxyPort))
{
exit(255);
}
char proxiedHost[ADDRESS_SIZE];
unsigned short proxiedPort;
if (!getHostAndPort(argc, argv, ARG_PORT + 1, ARG_PORT + 2, proxiedHost, ADDRESS_SIZE, &proxiedPort))
{
exit(255);
}
SOCKET sdProxyServer;
if ((sdProxyServer = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_FAILED)
{
printError(NULL);
return false;
}
printf("socker:proxy() socket created\n");
struct sockaddr_in sin;
if (!populateSockAddr(proxyHost, proxyPort, &sin))
{
return false;
}
printf("socker:proxy() about to bind on proxyPort\n");
if (bind(sdProxyServer, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) == BIND_FAILED)
{
printError(NULL);
return false;
}
SOCKET sdProxied;
struct sockaddr_in sinProxied;
if (!populateSockAddr(proxiedHost, proxiedPort, &sinProxied))
{
return false;
}
printf("about to create proxied socket\n");
if ((sdProxied = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_FAILED)
{
char errbuff[SCRATCH_BUFFER_SIZE];
sprintf(errbuff,"socker:proxy() failed to connect to proxied socket %s %d\n", proxiedHost, proxiedPort);
printError(errbuff);
return false;
}
printf("about to connect to proxied socket\n");
if((connect(sdProxied,(struct sockaddr *)&sinProxied,sizeof(sinProxied))) == CONNECT_FAILED)
{
printError(NULL);
return false;
}
// listen for connections and echo messages back to the peer
while (true)
{
printf("socket:proxy() about to call listen()\n");
if (listen(sdProxyServer, 10) == SOCKET_FAILED)
{
printError("listen failed:");
return false;
}
else
{
SOCKET sdClient;
printf("socker:proxy() about to call accept()\n");
if ((sdClient = accept(sdProxyServer, NULL, NULL)) == SOCKET_FAILED)
{
printError("accept failed:");
return false;
}
char buffer[1024];
printf("socker:proxy() about to call read()\n");
ONE_TIME_BUFFER_HANDLE fromClientBuffer = createOneTimeBuffer((char *)"From Client");
ONE_TIME_BUFFER_HANDLE toClientBuffer = createOneTimeBuffer((char * )"To Client");
ssize_t numBytes;
do
{
fd_set rfds;
fd_set wfds;
fd_set exceptfds;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&exceptfds);
FD_SET(sdProxied, &rfds);
FD_SET(sdProxied, &exceptfds);
FD_SET(sdClient, &rfds);
FD_SET(sdClient, &exceptfds);
if (availableBytesInOTB(fromClientBuffer) > 0)
{
FD_SET(sdProxied, &wfds);
}
if (availableBytesInOTB(toClientBuffer) > 0)
{
FD_SET(sdClient, &wfds);
}
int fdCap = max(sdClient, sdProxied) + 1;
select(fdCap, &rfds, &wfds, &exceptfds, NULL);
if (FD_ISSET(sdProxied, &exceptfds) || FD_ISSET(sdClient, &exceptfds))
{
printf("socker:proxy() exception in select\n");
}
if (FD_ISSET(sdClient, &rfds))
{
memset(buffer, '\0', sizeof(buffer));
numBytes = recv(sdClient, buffer, sizeof(buffer), 0);
if (numBytes == -1)
{
printError("socker:proxy() read failed:");
break;
}
else if (numBytes > 0)
{
printf("socker:proxy() about to print buffer from client\n");
printf("%s", buffer);
printf("\n");
writeOTB(fromClientBuffer, buffer, numBytes);
}
else
{
printf("socker:proxy() read of zero bytes performed\n");
printError("socker:proxy() zero bytes read error from client");
break;
}
}
if (FD_ISSET(sdProxied, &rfds))
{
memset(buffer, '\0', sizeof(buffer));
numBytes = recv(sdProxied, buffer, sizeof(buffer), 0);
if (numBytes == -1)
{
printError("socker:proxy() sdProxied read failed:");
break;
}
else if (numBytes > 0)
{
printf("socker:proxy() about to print buffer from proxied\n");
printf("%s", buffer);
printf("\n");
writeOTB(toClientBuffer, buffer, numBytes);
}
else
{
printf("socker:proxy() proxied read of zero bytes performed\n");
printError("socker:proxy() zero bytes read error from proxied");
break;
}
}
if (FD_ISSET(sdProxied, &wfds))
{
ssize_t numBytesToWrite;
char * writeBuffer;
if (getAndLockOTBForRead(fromClientBuffer, &writeBuffer, &numBytesToWrite))
{
printf("socker:proxy() about to send to proxied\n");
ssize_t numBytesWritten = send(sdProxied, writeBuffer, (size_t)numBytesToWrite, 0);
unlockOTB(fromClientBuffer, numBytesWritten);
}
}
if (FD_ISSET(sdClient, &wfds))
{
ssize_t numBytesToWrite;
char * writeBuffer;
if (getAndLockOTBForRead(toClientBuffer, &writeBuffer, &numBytesToWrite))
{
printf("socker:proxy() about to send to client");
ssize_t numBytesWritten = send(sdClient, writeBuffer, (size_t)numBytesToWrite, 0);
unlockOTB(toClientBuffer, numBytesWritten);
}
}
} while (true); // while reading a message
close(sdClient);
} // while listening
}
}