void StreamBuffer::put(unsigned char by){ std::size_t last_avail = 0; if(m_last){ last_avail = sizeof(m_last->data) - m_last->end; } Chunk *last_chunk = NULLPTR; if(last_avail != 0){ last_chunk = m_last; } else { AUTO(chunk, new Chunk); chunk->next = NULLPTR; // chunk->prev = NULLPTR; chunk->begin = 0; chunk->end = 0; if(m_last){ m_last->next = chunk; } else { m_first = chunk; } chunk->prev = m_last; m_last = chunk; if(!last_chunk){ last_chunk = chunk; } } AUTO(chunk, last_chunk); chunk->data[chunk->end] = by; ++(chunk->end); ++m_size; }
void StreamBuffer::unget(unsigned char by){ std::size_t first_avail = 0; if(m_first){ first_avail = m_first->begin; } Chunk *first_chunk = NULLPTR; if(first_avail != 0){ first_chunk = m_first; } else { AUTO(chunk, new Chunk); // chunk->next = NULLPTR; chunk->prev = NULLPTR; chunk->begin = sizeof(chunk->data); chunk->end = sizeof(chunk->data); if(m_first){ m_first->prev = chunk; } else { m_last = chunk; } chunk->next = m_first; m_first = chunk; if(!first_chunk){ first_chunk = chunk; } } AUTO(chunk, first_chunk); --(chunk->begin); chunk->data[chunk->begin] = by; ++m_size; }
StreamBuffer::StreamBuffer(const StreamBuffer &rhs) : m_first(NULLPTR), m_last(NULLPTR), m_size(0) { for(AUTO(ce, rhs.get_chunk_enumerator()); ce; ++ce){ put(ce.data(), ce.size()); } }
boost::shared_ptr<const JobPromise> DnsDaemon::enqueue_for_looking_up(boost::shared_ptr<SockAddr> sock_addr, std::string host, unsigned port){ PROFILE_ME; AUTO(promise, boost::make_shared<JobPromise>()); const AUTO(param, new DnsCallbackParam(STD_MOVE(sock_addr), host, port, promise)); atomic_add(g_pending_callback_count, 1, ATOMIC_RELAXED); // noexcept try { ::sigevent sev; sev.sigev_notify = SIGEV_THREAD; sev.sigev_value.sival_ptr = param; sev.sigev_notify_function = &dns_callback; sev.sigev_notify_attributes = NULLPTR; AUTO(pcb, &(param->cb)); const int gai_code = ::getaddrinfo_a(GAI_NOWAIT, &pcb, 1, &sev); // noexcept if(gai_code != 0){ LOG_POSEIDON_WARNING("DNS failure: gai_code = ", gai_code, ", err_msg = ", ::gai_strerror(gai_code)); DEBUG_THROW(Exception, sslit("DNS failure")); } } catch(...){ atomic_sub(g_pending_callback_count, 1, ATOMIC_RELAXED); // noexcept delete param; throw; } return promise; }
std::ostream &operator<<(std::ostream &os, const StringEscaper &rhs){ os <<'\''; for(AUTO(it, rhs.str.begin()); it != rhs.str.end(); ++it){ switch(*it){ case 0: os.put('\\').put('0'); break; case 0x1A: os.put('\\').put('Z'); break; case '\r': os.put('\\').put('r'); break; case '\n': os.put('\\').put('n'); break; case '\\': os.put('\\').put('\\'); break; case '\'': os.put('\\').put('\''); break; case '\"': os.put('\\').put('\"'); break; default: os.put(*it); break; } } os <<'\''; return os; }
static bool over(ConstLine &a, ConstLine &b, ConstLine &c) { AUTO(res, intersect(a, b)); // We already remove all lines that has the same slope. // So any two lines should always intersect each other. assert(res.size() == 1); return position(c[0], res[0], c[1]) == state::left; }
TEST(math, gen_prime_fast) { AUTO(ans, sbl::generate_prime_fast(10)); const std::string s = "00110101000"; EXPECT_EQ(ans.size(), s.size()); for (size_t i = 0; i < ans.size(); i++) EXPECT_EQ(ans[i], s[i] == '1'); }
long ClientWriter::put_request_headers(RequestHeaders request_headers){ PROFILE_ME; StreamBuffer data; data.put(get_string_from_verb(request_headers.verb)); data.put(' '); data.put(request_headers.uri); if(!request_headers.get_params.empty()){ data.put('?'); data.put(url_encoded_from_optional_map(request_headers.get_params)); } char temp[64]; const unsigned ver_major = request_headers.version / 10000, ver_minor = request_headers.version % 10000; unsigned len = (unsigned)std::sprintf(temp, " HTTP/%u.%u\r\n", ver_major, ver_minor); data.put(temp, len); AUTO_REF(headers, request_headers.headers); for(AUTO(it, headers.begin()); it != headers.end(); ++it){ data.put(it->first.get()); data.put(": "); data.put(it->second); data.put("\r\n"); } data.put("\r\n"); return on_encoded_data_avail(STD_MOVE(data)); }
TEST(math, gen_mobius) { AUTO(ans, sbl::generate_mobius(100)); int a[] = {0, 1, -1, -1, 0, -1, 1, -1, 0, 0, 1, -1, 0, -1, 1, 1, 0, -1, 0, -1, 0, 1, 1, -1, 0, 0, cSentinel }; for (int i = 1; a[i] != cSentinel; i++) EXPECT_EQ(a[i], ans[i]); }
int Compute( void ) { if (!AUTO(gIData)) return 0; else { return 1; } }
TEST(math, gen_euler) { AUTO(ans, sbl::generate_euler(100)); int a[] = {0, 1, 1, 2, 2, 4, 2, 6, 4, 6, 4, 10, 4, 12, 6, 8, 8, 16, 6, 18, 8, 12, 10, 22, 8, 20, 12, cSentinel }; for (int i = 1; a[i] != cSentinel; i++) EXPECT_EQ(a[i], ans[i]); }
long ClientWriter::put_chunked_header(RequestHeaders request_headers){ PROFILE_ME; StreamBuffer data; data.put(get_string_from_verb(request_headers.verb)); data.put(' '); data.put(request_headers.uri); if(!request_headers.get_params.empty()){ data.put('?'); data.put(url_encoded_from_optional_map(request_headers.get_params)); } char temp[64]; const unsigned ver_major = request_headers.version / 10000, ver_minor = request_headers.version % 10000; unsigned len = (unsigned)std::sprintf(temp, " HTTP/%u.%u\r\n", ver_major, ver_minor); data.put(temp, len); AUTO_REF(headers, request_headers.headers); if(!headers.has("Content-Type")){ headers.set(sslit("Content-Type"), "application/x-www-form-urlencoded; charset=utf-8"); } AUTO(transfer_encoding, headers.get("Transfer-Encoding")); AUTO(pos, transfer_encoding.find(';')); if(pos != std::string::npos){ transfer_encoding.erase(pos); } transfer_encoding = to_lower_case(trim(STD_MOVE(transfer_encoding))); if(transfer_encoding.empty() || (transfer_encoding == STR_IDENTITY)){ headers.set(sslit("Transfer-Encoding"), STR_CHUNKED); } else { headers.set(sslit("Transfer-Encoding"), STD_MOVE(transfer_encoding)); } for(AUTO(it, headers.begin()); it != headers.end(); ++it){ data.put(it->first.get()); data.put(": "); data.put(it->second); data.put("\r\n"); } data.put("\r\n"); return on_encoded_data_avail(STD_MOVE(data)); }
void vint50ToBinary(boost::int64_t val, OutputIterT &write){ AUTO(encoded, static_cast<boost::uint64_t>(val)); encoded <<= 1; if(val < 0){ encoded = ~encoded; } encoded &= (1ull << 50) - 1; vuint50ToBinary(encoded, write); }
StreamBuffer StreamBuffer::cut_off(std::size_t bytes){ StreamBuffer ret; const AUTO(bytes_to_copy, std::min(bytes, m_size)); if(bytes_to_copy == 0){ return ret; } if(m_size <= bytes_to_copy){ ret.swap(*this); return ret; } std::size_t bytes_copied = 0; AUTO(cut_end, m_first); for(;;){ const AUTO(bytes_remaining, bytes_to_copy - bytes_copied); const AUTO(bytes_avail, cut_end->end - cut_end->begin); if(bytes_remaining <= bytes_avail){ if(bytes_remaining == bytes_avail){ cut_end = cut_end->next; } else { const AUTO(chunk, new Chunk); chunk->next = cut_end; chunk->prev = cut_end->prev; chunk->begin = 0; chunk->end = bytes_remaining; std::memcpy(chunk->data, cut_end->data + cut_end->begin, bytes_remaining); cut_end->begin += bytes_remaining; if(cut_end->prev){ cut_end->prev->next = chunk; } else { m_first = chunk; } cut_end->prev = chunk; } break; } bytes_copied += bytes_avail; cut_end = cut_end->next; } const AUTO(cut_first, m_first); const AUTO(cut_last, cut_end->prev); cut_last->next = NULLPTR; cut_end->prev = NULLPTR; m_first = cut_end; m_size -= bytes_to_copy; ret.m_first = cut_first; ret.m_last = cut_last; ret.m_size = bytes_to_copy; return ret; }
static int decryptd(int argc, char *argv[]) { int ret = EXIT_FAILURE; AUTO(DEO_MSG, in); AUTO(BIO, sio); AUTO(ctx, ctx); ctx = load_ctx(argc, argv); if (ctx == NULL) goto error; sio = start_tls(ctx->ctx); if (sio == NULL) goto error; in = d2i_bio_max(&DEO_MSG_it, sio, NULL, DEO_MAX_INPUT); if (in == NULL) goto error; switch (in->type) { case DEO_MSG_TYPE_CRT_REQ: ASN1_item_i2d_bio(&DEO_MSG_it, sio, &(DEO_MSG) { .type = DEO_MSG_TYPE_CRT_REP, .value.crt_rep = ctx->crt }); break; case DEO_MSG_TYPE_DEC_REQ: { DEO_ERR err = DEO_ERR_NONE; AUTO(ASN1_OCTET_STRING, pt); err = decrypt(ctx, in->value.dec_req, &pt); if (err != DEO_ERR_NONE) { SEND_ERR(sio, err); break; } ASN1_item_i2d_bio(&DEO_MSG_it, sio, &(DEO_MSG) { .type = DEO_MSG_TYPE_DEC_REP, .value.dec_rep = pt }); break; }
inline std::string implode(char separator, const std::vector<std::string> &vec){ std::string ret; for(AUTO(it, vec.begin()); it != vec.end(); ++it){ ret.append(*it); if(separator != 0){ ret.push_back(separator); } } return ret; }
void * d2i_fp_max(const ASN1_ITEM *it, FILE *fp, void *x, unsigned int max) { AUTO(BIO, bio); bio = BIO_new_fp(fp, BIO_NOCLOSE); if (bio == NULL) return NULL; return d2i_bio_max(it, bio, x, max); }
static EVP_PKEY * load_prv(const char *filename) { AUTO(BIO, bio); bio = BIO_new_file(filename, "r"); if (bio == NULL) return NULL; return PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL); }
static STACK_OF(X509_INFO) * load_decryption_certs_keys(const char *dirname) { AUTO_STACK(X509_INFO, infos); AUTO(DIR, dir); if (dirname == NULL) return NULL; infos = sk_X509_INFO_new_null(); if (infos == NULL) return NULL; dir = opendir(dirname); if (dir == NULL) return NULL; for (struct dirent *de = readdir(dir); de != NULL; de = readdir(dir)) { char path[strlen(dirname) + strlen(de->d_name) + 2]; AUTO(FILE, file); if (!deo_isreg(dirname, de)) continue; strcpy(path, dirname); strcat(path, "/"); strcat(path, de->d_name); file = fopen(path, "r"); if (file == NULL) return NULL; if (PEM_X509_INFO_read(file, infos, NULL, NULL) == NULL) return NULL; } if (sk_X509_INFO_num(infos) == 0) return NULL; return STEAL(infos); }
bool TcpServerBase::poll() const { UniqueFile client(::accept(get_fd(), NULLPTR, NULLPTR)); if(!client){ if(errno != EAGAIN){ DEBUG_THROW(SystemException); } return false; } AUTO(session, on_client_connect(STD_MOVE(client))); if(!session){ LOG_POSEIDON_WARNING("on_client_connect() returns a null pointer."); DEBUG_THROW(Exception, sslit("Null client pointer")); } if(m_ssl_factory){ AUTO(ssl, m_ssl_factory->create_ssl()); boost::scoped_ptr<SslFilterBase> filter(new SslFilter(STD_MOVE(ssl), session->get_fd())); session->init_ssl(STD_MOVE(filter)); } session->set_timeout(EpollDaemon::get_tcp_request_timeout()); EpollDaemon::add_session(session); LOG_POSEIDON_INFO("Accepted TCP connection from ", session->get_remote_info()); return true; }
void TcpClientBase::realConnect(bool useSsl){ if(::connect(m_socket.get(), static_cast<const ::sockaddr *>(SockAddr::getData()), SockAddr::getSize()) != 0){ if(errno != EINPROGRESS){ DEBUG_THROW(SystemException); } } if(useSsl){ LOG_POSEIDON_INFO("Initiating SSL handshake..."); AUTO(ssl, g_clientSslFactory.createSsl()); boost::scoped_ptr<SslFilterBase> filter(new SslFilter(STD_MOVE(ssl), getFd())); initSsl(STD_MOVE(filter)); } }
~FiberControl(){ AUTO(it, g_stack_pool.begin()); for(;;){ if(it == g_stack_pool.end()){ stack.reset(); break; } if(!*it){ stack.swap(*it); break; } ++it; } }
std::vector<EpollDaemon::SnapshotElement> EpollDaemon::snapshot(){ std::vector<boost::shared_ptr<TcpSessionBase> > sessions; g_epoll->snapshot(sessions); std::vector<SnapshotElement> ret; const AUTO(now, getFastMonoClock()); for(AUTO(it, sessions.begin()); it != sessions.end(); ++it){ ret.push_back(SnapshotElement()); AUTO_REF(item, ret.back()); item.remote = (*it)->getRemoteInfo(); item.local = (*it)->getLocalInfo(); item.msOnline = now - (*it)->getCreatedTime(); } return ret; }
bool operator()(EOT&) { #ifdef TRACE AUTO(std_or_boost::chrono::time_point< std_or_boost::chrono::system_clock >) start = std_or_boost::chrono::system_clock::now(); #endif /*std_or_*/boost::this_thread::sleep_for(/*std_or_*/boost::chrono::microseconds( int(_timeout * 1000) )); #ifdef TRACE long elapsed = std_or_boost::chrono::duration_cast<std_or_boost::chrono::microseconds>(std_or_boost::chrono::system_clock::now()-start).count(); // micro _of << elapsed / 1000. << " "; _of.flush(); #endif return true; }
long ClientWriter::put_chunked_trailer(OptionalMap headers){ PROFILE_ME; StreamBuffer data; data.put("0\r\n"); for(AUTO(it, headers.begin()); it != headers.end(); ++it){ data.put(it->first.get()); data.put(": "); data.put(it->second); data.put("\r\n"); } data.put("\r\n"); return on_encoded_data_avail(STD_MOVE(data)); }
explicit FiberControl(Initializer) : state(FS_READY) { AUTO(it, g_stack_pool.begin()); for(;;){ if(it == g_stack_pool.end()){ stack.reset(new StackStorage); break; } if(*it){ stack.swap(*it); break; } ++it; } }
inline std::string implode(char separator, const std::vector<T> &vec){ std::ostringstream oss; for(AUTO(it, vec.begin()); it != vec.end(); ++it){ oss <<*it; if(separator != 0){ oss.put(separator); } } std::string ret = oss.str(); if(!ret.empty()){ #ifdef POSEIDON_CXX11 ret.pop_back(); #else ret.erase(ret.end() - 1, ret.end()); #endif } return ret; }
static BIO * start_tls(SSL_CTX *ctx) { AUTO(BIO, sio); SSL *ssl; sio = BIO_new_ssl(ctx, 0); if (sio == NULL) return NULL; if (BIO_get_ssl(sio, &ssl) <= 0) return NULL; if (SSL_set_fd(ssl, SD_LISTEN_FDS_START) <= 0) return NULL; SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY); return STEAL(sio); }
bool isValidUtf8String(const std::string &str){ PROFILE_ME; boost::uint32_t codePoint; for(AUTO(it, str.begin()); it != str.end(); ++it){ codePoint = static_cast<unsigned char>(*it); if((codePoint & 0x80) == 0){ continue; } const AUTO(bytes, (unsigned)__builtin_clz((~codePoint | 1) & 0xFF) - (sizeof(unsigned) - 1) * CHAR_BIT); if(bytes - 2 > 2){ // 2, 3, 4 LOG_POSEIDON_WARNING("Invalid UTF-8 leading byte: bytes = ", bytes); return false; } codePoint &= (0xFFu >> bytes); for(unsigned i = 1; i < bytes; ++i){ ++it; if(it == str.end()){ LOG_POSEIDON_WARNING("String is truncated."); return false; } const unsigned trailing = static_cast<unsigned char>(*it); if((trailing & 0xC0u) != 0x80u){ LOG_POSEIDON_WARNING("Invalid UTF-8 trailing byte: trailing = 0x", std::hex, std::setw(2), std::setfill('0'), trailing); return false; } } if(codePoint > 0x10FFFFu){ LOG_POSEIDON_WARNING("Invalid UTF-8 code point: codePoint = 0x", std::hex, std::setw(6), std::setfill('0'), codePoint); return false; } if(codePoint - 0xD800u < 0x800u){ LOG_POSEIDON_WARNING("UTF-8 code point is reserved for UTF-16: codePoint = 0x", std::hex, std::setw(4), std::setfill('0'), codePoint); return false; } } return true; }
std::vector<ProfileDepository::SnapshotElement> ProfileDepository::snapshot(){ Profiler::accumulate_all_in_thread(); std::vector<SnapshotElement> ret; { const Mutex::UniqueLock lock(g_mutex); ret.reserve(g_profile.size()); for(AUTO(it, g_profile.begin()); it != g_profile.end(); ++it){ const AUTO_REF(key, it->first); const AUTO_REF(counters, it->second); SnapshotElement elem; elem.file = key.file; elem.line = key.line; elem.func = key.func; elem.samples = atomic_load(counters.samples, ATOMIC_RELAXED); elem.ns_total = atomic_load(counters.ns_total, ATOMIC_RELAXED); elem.ns_exclusive = atomic_load(counters.ns_exclusive, ATOMIC_RELAXED); ret.push_back(elem); } } return ret; }