Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <netinet/tcp.h>
- #include <unistd.h>
- #include <sched.h>
- #include <exception>
- #include <string.h>
- #include <thread>
- #include <atomic>
- #include <arpa/inet.h>
- #include <sys/fcntl.h>
- #include <openssl/md5.h>
- #include <vector>
- int safe_call(int ret, const char * ctx) {
- // fprintf(stderr, "%s == %d, errno(%d) == %s\n", ctx, ret, errno, strerror(errno));
- if(ret == -1) throw std::runtime_error(std::string(ctx) + " == " + std::to_string(ret) + ", errno(" + std::to_string(errno) + ')' + " == " + strerror(errno));
- return ret;
- }
- #define safe_call(call) safe_call(call, #call)
- #define PCKT_SZ 1024
- class alignas(64) worker {
- public:
- void run(int listen_fd) {
- this->listen_fd = listen_fd;
- std::thread([this]() {
- work();
- }).detach();
- }
- protected:
- bool read_buf(int fd, uint8_t *buf, size_t len) {
- do {
- size_t r;
- if ((r = safe_call(read(fd, buf, len))) == 0)
- return false;
- len -= r;
- buf += r;
- } while (len);
- return true;
- }
- bool write_buf(int fd, const uint8_t *buf, size_t len) {
- do {
- size_t w;
- if ((w = safe_call(write(fd, buf, len))) == 0)
- return false;
- len -= w;
- buf += w;
- } while (len);
- return true;
- }
- void work() {
- fprintf(stderr, "start thread(%lu)\n", id);
- while(int accept_fd = safe_call(accept(listen_fd, nullptr, nullptr))) {
- //fprintf(stderr, "accept thread(%lu)\n", id);
- std::vector<uint8_t> resp(PCKT_SZ, 0); // Heap
- uint8_t req[PCKT_SZ]; // Stack
- uint8_t md5digest[MD5_DIGEST_LENGTH];
- if (read_buf(accept_fd, req, PCKT_SZ)) {
- uint8_t *it = resp.data(), *end = it + ((PCKT_SZ / MD5_DIGEST_LENGTH) * MD5_DIGEST_LENGTH);
- MD5(req, PCKT_SZ, md5digest);
- do {
- memcpy(it, md5digest, MD5_DIGEST_LENGTH);
- it += MD5_DIGEST_LENGTH;
- } while (it < end);
- write_buf(accept_fd, resp.data(), resp.size());
- }
- shutdown(accept_fd, SHUT_RDWR);
- close(accept_fd);
- }
- }
- protected:
- size_t id = get_tid();
- int listen_fd;
- protected:
- size_t get_tid() {
- return tid_count++;
- }
- static inline size_t tid_count = 0;;
- };
- int listen_to(in_addr_t addr, uint16_t port) {
- constexpr size_t n = 100;
- sockaddr_in saddr{};
- saddr.sin_family = AF_INET;
- saddr.sin_port = htons(port);
- saddr.sin_addr.s_addr = htonl(addr);
- int listen_fd = safe_call(socket(AF_INET, SOCK_STREAM, 0));
- int option = 1;
- safe_call(setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)));
- safe_call(bind(listen_fd, (__CONST_SOCKADDR_ARG)&saddr, sizeof(saddr)));
- safe_call(listen(listen_fd, n));
- return listen_fd;
- }
- worker workers[10000];
- int main() {
- int listen_fd = listen_to(INADDR_LOOPBACK, 8888);
- for(auto & w : workers) w.run(listen_fd);
- while(1) {sleep(1);};
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement