Advertisement
Guest User

Untitled

a guest
Dec 12th, 2018
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.80 KB | None | 0 0
  1. #include <signal.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <unistd.h>
  5. #include <netdb.h>
  6. #include <arpa/inet.h>
  7. #include <sys/socket.h>
  8. #include <poll.h>
  9. #include <stdlib.h>
  10.  
  11. #define SOCKETCOUNT (1 + 120 * 2)
  12. #define BUFFERSIZE 100 * 1024
  13. #define DNS_TIMEOUT 10
  14.  
  15. struct attr {
  16. char buffer[BUFFERSIZE];
  17. int start;
  18. int end;
  19. };
  20.  
  21. void initialize(struct pollfd *sockets, struct attr *attrs, int serverSocket) {
  22. for (int i = 0; i < SOCKETCOUNT; i++) {
  23. sockets[i].fd = -1;
  24. sockets[i].events = 0;
  25.  
  26. attrs[i].start = 0;
  27. attrs[i].end = 0;
  28. }
  29.  
  30. sockets[0].fd = serverSocket;
  31. sockets[0].events = POLLIN;
  32. }
  33.  
  34. int acceptNewConnection(struct pollfd *sockets, struct attr *attrs, int connectionCount, struct sockaddr_in destinationAddress, int serverSocket) {
  35. struct sockaddr_in incomingAddress;
  36. int incomingAddressLength = sizeof(incomingAddress);
  37.  
  38. int incomingSocket = accept(serverSocket, (struct sockaddr *) &incomingAddress,
  39. (socklen_t * ) & incomingAddressLength);
  40.  
  41. if (-1 == incomingSocket) {
  42. perror("accept error");
  43. exit(EXIT_FAILURE);
  44. }
  45.  
  46. if (connectionCount < 120) {
  47. int outcomingSocket = socket(AF_INET, SOCK_STREAM, 0);
  48.  
  49. if (-1 == outcomingSocket) {
  50. perror("Cannot create outccoming socket");
  51. exit(EXIT_FAILURE);
  52. }
  53.  
  54. int err = connect(outcomingSocket, (struct sockaddr *) &destinationAddress, sizeof(destinationAddress));
  55. if (-1 == err) {
  56. perror("Cannot connect to remote");
  57. exit(EXIT_FAILURE);
  58. }
  59.  
  60. for (int j = 1; j < SOCKETCOUNT; j += 2) {
  61. if (-1 == sockets[j].fd) {
  62.  
  63. sockets[j].fd = incomingSocket;
  64. sockets[j + 1].fd = outcomingSocket;
  65.  
  66. sockets[j].events = POLLIN;
  67. sockets[j + 1].events = POLLIN;
  68.  
  69. attrs[j].start = 0;
  70. attrs[j].end = 0;
  71.  
  72. attrs[j + 1].start = 0;
  73. attrs[j + 1].end = 0;
  74.  
  75. return 0;
  76. }
  77. }
  78. } else {
  79. close(incomingSocket);
  80. }
  81.  
  82. return 1;
  83. }
  84.  
  85. int readFromSocket(struct pollfd *sockets, struct attr *attrs, int i, int other) {
  86. if (BUFFERSIZE != attrs[i].end)
  87. {
  88. int received = read(sockets[i].fd, attrs[i].buffer + attrs[i].end, BUFFERSIZE - attrs[i].end);
  89.  
  90. switch (received) {
  91. case -1:
  92. perror("read error");
  93. exit(EXIT_FAILURE);
  94. case 0:
  95. close(sockets[i].fd);
  96. sockets[i].fd = -1;
  97. sockets[i].events = 0;
  98.  
  99. if (0 == attrs[i].end) {
  100. close(sockets[other].fd);
  101. sockets[other].fd = -1;
  102. sockets[other].events = 0;
  103.  
  104. return 0;
  105. }
  106. break;
  107. default:
  108. attrs[i].end += received;
  109.  
  110. if (BUFFERSIZE == attrs[i].end) {
  111. sockets[i].events = sockets[i].events & (~POLLIN);
  112. }
  113.  
  114. sockets[other].events = sockets[other].events | POLLOUT;
  115. break;
  116. }
  117. }
  118.  
  119. return 1;
  120. }
  121.  
  122. int writeToSocket(struct pollfd *sockets, struct attr *attrs, int i, int other) {
  123. if (0 != attrs[other].end) {
  124. int written = send(sockets[i].fd, attrs[other].buffer + attrs[other].start,
  125. attrs[other].end - attrs[other].start, 0);
  126.  
  127. switch (written) {
  128. case -1:
  129. perror("write error");
  130. exit(EXIT_FAILURE);
  131. case 0:
  132. close(sockets[i].fd);
  133. sockets[i].fd = -1;
  134. sockets[i].events = 0;
  135.  
  136. if (0 == attrs[i].end) {
  137. close(sockets[other].fd);
  138. sockets[other].fd = -1;
  139. sockets[other].events = 0;
  140.  
  141. return 0;
  142. }
  143. break;
  144.  
  145. default:
  146. attrs[other].start += written;
  147.  
  148. if (attrs[other].start == attrs[other].end) {
  149. if (-1 == sockets[other].fd) {
  150. close(sockets[i].fd);
  151. sockets[i].fd = -1;
  152. sockets[i].events = 0;
  153.  
  154. return 0;
  155. } else {
  156. attrs[other].start = 0;
  157. attrs[other].end = 0;
  158.  
  159. sockets[i].events = sockets[i].events & (~POLLOUT);
  160. sockets[other].events = sockets[other].events | POLLIN;
  161. }
  162. }
  163. }
  164. } else if (-1 == sockets[other].fd)
  165. {
  166. close(sockets[i].fd);
  167. sockets[i].fd = -1;
  168. sockets[i].events = 0;
  169.  
  170. return 0;
  171. }
  172.  
  173. return 1;
  174. }
  175.  
  176. void work(int serverSocket, struct sockaddr_in destinationAddress) {
  177. struct pollfd *sockets = (struct pollfd*) malloc(SOCKETCOUNT * sizeof(struct pollfd));
  178. struct attr *attrs = (struct attr*) malloc(SOCKETCOUNT * sizeof(struct attr));
  179.  
  180. initialize(sockets, attrs, serverSocket);
  181.  
  182. int connectionCount = 0;
  183.  
  184. while(1) {
  185. int readyCount = poll(sockets, SOCKETCOUNT, -1);
  186.  
  187. if (-1 == readyCount) {
  188. perror("poll error");
  189. exit(EXIT_FAILURE);
  190. }
  191. else if (0 == readyCount) {
  192. continue;
  193. }
  194.  
  195. if (0 != (sockets[0].revents & POLLIN)) {
  196. if (0 == acceptNewConnection(sockets, attrs, connectionCount, destinationAddress, serverSocket)) {
  197. connectionCount++;
  198. }
  199. readyCount--;
  200. }
  201.  
  202. for (int i = 1; i < SOCKETCOUNT && readyCount > 0; i++) {
  203. int other;
  204.  
  205. if (1 == i % 2) {
  206. other = i + 1;
  207. }
  208. else {
  209. other = i - 1;
  210. }
  211.  
  212. if (0 != (sockets[i].revents & POLLIN)) {
  213. if (readFromSocket(sockets, attrs, i, other) == 0) {
  214. connectionCount--;
  215. }
  216.  
  217. readyCount--;
  218. }
  219. else if (0 != (sockets[i].revents & POLLOUT)) {
  220. if (writeToSocket(sockets, attrs, i, other) == 0) {
  221. connectionCount--;
  222. }
  223.  
  224. readyCount--;
  225. } else if (0 != (sockets[i].revents & POLLHUP)) {
  226. exit(EXIT_SUCCESS);
  227. }
  228. }
  229.  
  230. if (connectionCount >= 510) {
  231. sockets[0].fd = -1;
  232. } else {
  233. sockets[0].fd = serverSocket;
  234. }
  235. }
  236.  
  237. free(sockets);
  238. free(attrs);
  239. }
  240.  
  241. void sighandler(int signum) {
  242. fprintf(stderr, "Dns request timed out\n");
  243. exit(EXIT_FAILURE);
  244. }
  245.  
  246. struct sockaddr_in getDestinationAddress(const char *hostName, int remotePort) {
  247. signal(SIGALRM, sighandler);
  248. alarm(DNS_TIMEOUT);
  249. struct hostent *hostInfo = gethostbyname(hostName);
  250. alarm(0);
  251.  
  252. if (NULL == hostInfo) {
  253. fprintf(stderr, "Cannot get host by name\n");
  254. exit(EXIT_FAILURE);
  255. }
  256.  
  257. struct sockaddr_in destinationAddress;
  258.  
  259. destinationAddress.sin_family = AF_INET;
  260. destinationAddress.sin_port = htons(remotePort);
  261. memcpy(&destinationAddress.sin_addr, hostInfo->h_addr, hostInfo->h_length);
  262.  
  263. return destinationAddress;
  264. }
  265.  
  266. int createServerSocket(int serverPort) {
  267. int serverSocket = socket(AF_INET, SOCK_STREAM, 0);
  268.  
  269. if (-1 == serverSocket) {
  270. perror("Cannot create serverSocket");
  271. exit(EXIT_FAILURE);
  272. }
  273.  
  274. struct sockaddr_in serverAddress;
  275.  
  276. serverAddress.sin_family = AF_INET;
  277. serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
  278. serverAddress.sin_port = htons(serverPort);
  279.  
  280. if (-1 == bind(serverSocket, (struct sockaddr *) &serverAddress, sizeof(serverAddress))) {
  281. perror("binding error");
  282. exit(EXIT_FAILURE);
  283. }
  284.  
  285. if (-1 == listen(serverSocket, 1024)) {
  286. perror("listen error");
  287. exit(EXIT_FAILURE);
  288. }
  289.  
  290. return serverSocket;
  291. }
  292.  
  293. void checkCountArguments(int argc) {
  294. if (argc != 4) {
  295. perror("Wrong count of arguments");
  296. exit(EXIT_FAILURE);
  297. }
  298. }
  299.  
  300. int main(int argc, char *argv[]) {
  301. checkCountArguments(argc);
  302.  
  303. int serverPort = atoi(argv[1]);
  304. int remotePort = atoi(argv[3]);
  305.  
  306. if (0 == serverPort) {
  307. perror("Incorrect port for listening");
  308. exit(EXIT_FAILURE);
  309. }
  310.  
  311. struct sockaddr_in destinationAddress = getDestinationAddress(argv[2], remotePort);
  312. int serverSocket = createServerSocket(serverPort);
  313.  
  314. work(serverSocket, destinationAddress);
  315.  
  316.  
  317. putchar('\n');
  318.  
  319. return EXIT_SUCCESS;
  320. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement