Advertisement
Guest User

Untitled

a guest
Jul 18th, 2017
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.01 KB | None | 0 0
  1. #include <iostream>
  2. #include <sys/mman.h>
  3. #include <sys/types.h>
  4. #include <sys/socket.h>
  5. #include <netinet/in.h>
  6. #include <netinet/tcp.h>
  7. #include <unistd.h>
  8. #include <sched.h>
  9. #include <exception>
  10. #include <string.h>
  11. #include <thread>
  12. #include <atomic>
  13. #include <arpa/inet.h>
  14. #include <sys/fcntl.h>
  15. #include <openssl/md5.h>
  16. #include <vector>
  17.  
  18. int safe_call(int ret, const char * ctx) {
  19. //   fprintf(stderr, "%s == %d, errno(%d) == %s\n", ctx, ret, errno, strerror(errno));
  20.   if(ret == -1) throw std::runtime_error(std::string(ctx) +  " == " + std::to_string(ret) + ", errno(" + std::to_string(errno) + ')'  + " == " + strerror(errno));
  21.   return ret;
  22. }
  23. #define safe_call(call) safe_call(call, #call)
  24.  
  25. #define PCKT_SZ 1024
  26.  
  27.  
  28. class alignas(64) worker {
  29. public:
  30.  
  31.   void run(int listen_fd) {
  32.     this->listen_fd = listen_fd;
  33.     std::thread([this]() {
  34.       work();
  35.     }).detach();
  36.   }
  37.  
  38. protected:
  39.  
  40.   bool read_buf(int fd, uint8_t *buf, size_t len) {
  41.     do {
  42.       size_t r;
  43.       if ((r = safe_call(read(fd, buf, len))) == 0)
  44.         return false;
  45.       len -= r;
  46.       buf += r;
  47.     } while (len);
  48.     return true;
  49.   }
  50.   bool write_buf(int fd, const uint8_t *buf, size_t len) {
  51.     do {
  52.       size_t w;
  53.       if ((w = safe_call(write(fd, buf, len))) == 0)
  54.         return false;
  55.       len -= w;
  56.       buf += w;
  57.     } while (len);
  58.     return true;
  59.   }
  60.   void work() {
  61.     fprintf(stderr, "start thread(%lu)\n", id);
  62.    
  63.     while(int accept_fd = safe_call(accept(listen_fd, nullptr, nullptr))) {
  64.       //fprintf(stderr, "accept thread(%lu)\n", id);
  65.       std::vector<uint8_t> resp(PCKT_SZ, 0); // Heap
  66.       uint8_t req[PCKT_SZ]; // Stack
  67.       uint8_t md5digest[MD5_DIGEST_LENGTH];
  68.  
  69.       if (read_buf(accept_fd, req, PCKT_SZ)) {
  70.         uint8_t *it = resp.data(), *end = it + ((PCKT_SZ / MD5_DIGEST_LENGTH) * MD5_DIGEST_LENGTH);
  71.         MD5(req, PCKT_SZ, md5digest);
  72.  
  73.         do {
  74.             memcpy(it, md5digest, MD5_DIGEST_LENGTH);
  75.             it += MD5_DIGEST_LENGTH;
  76.         } while (it < end);
  77.         write_buf(accept_fd, resp.data(), resp.size());
  78.       }
  79.       shutdown(accept_fd, SHUT_RDWR);
  80.       close(accept_fd);
  81.     }
  82.   }
  83.  
  84. protected:
  85.   size_t id = get_tid();
  86.   int listen_fd;
  87. protected:
  88.   size_t get_tid() {
  89.     return tid_count++;
  90.   }
  91.   static inline size_t tid_count = 0;;
  92. };
  93.  
  94.  
  95. int listen_to(in_addr_t addr, uint16_t port) {
  96.   constexpr size_t n = 100;
  97.   sockaddr_in saddr{};
  98.   saddr.sin_family = AF_INET;
  99.   saddr.sin_port = htons(port);
  100.   saddr.sin_addr.s_addr = htonl(addr);
  101.   int listen_fd = safe_call(socket(AF_INET, SOCK_STREAM, 0));
  102.   int option = 1;
  103.   safe_call(setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)));
  104.   safe_call(bind(listen_fd, (__CONST_SOCKADDR_ARG)&saddr, sizeof(saddr)));
  105.   safe_call(listen(listen_fd, n));
  106.   return listen_fd;
  107. }
  108.  
  109. worker workers[10000];
  110.  
  111. int main() {
  112.   int listen_fd = listen_to(INADDR_LOOPBACK, 8888);
  113.  
  114.   for(auto & w : workers) w.run(listen_fd);
  115.   while(1) {sleep(1);};
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement