void ping::ping_all() { if (host_list_->empty()) { logger_error("ip empty"); return; } ACL_AIO *aio; /* 创建非阻塞异步通信句柄 */ aio = acl_aio_create(ACL_EVENT_SELECT); acl_aio_set_keep_read(aio, 0); /* 创建 ICMP 对象 */ __chat = icmp_chat_create(aio, 1); // 添加目标 IP 地址 std::vector<host_status*>::iterator it = host_list_->begin(); for (; it != host_list_->end(); ++it) { //icmp_ping_one(__chat, NULL, (*cit)->get_ip(), // npkt_, delay_, timeout_); // 创建一个 PING 的对象,并对该 IP 进行 PING 操作 ICMP_HOST* host = icmp_host_new(__chat, NULL, (*it)->get_ip(), npkt_, pkt_size_, delay_, timeout_); host->enable_log = 1; icmp_host_set(host, (*it), ping_stat_response, ping_stat_timeout, ping_stat_unreach, ping_stat_finish); icmp_chat(host); } total_pkt_ = npkt_ * host_list_->size(); rpc_signal(NULL); time_t last_signal = time(NULL), t; while (1) { /* 如果 PING 结束,则退出循环 */ if (icmp_chat_finish(__chat)) { logger("over now!, hosts' size=%d, count=%d", icmp_chat_size(__chat), icmp_chat_count(__chat)); break; } /* 异步事件循环过程 */ acl_aio_loop(aio); t = time(NULL); if (t - last_signal >= 1) { rpc_signal(NULL); // 通知主线程 last_signal = t; } } /* 显示 PING 结果 */ display_res(); /* 销毁非阻塞句柄 */ acl_aio_free(aio); }
void nslookup::lookup_all() { if (domain_list_ == NULL || domain_list_->empty()) { logger_error("domain empty"); return; } ACL_AIO *aio; /* 创建非阻塞异步通信句柄 */ aio = acl_aio_create(ACL_EVENT_SELECT); // acl_aio_set_keep_read(aio, 0); // 创建 DNS 查询句柄 ACL_DNS* dns = acl_dns_create(aio, timeout_); acl_dns_add_dns(dns, dns_ip_.c_str(), dns_port_, 24); rpc_signal(NULL); time_t last_signal = time(NULL), t; // 添加目标 domain 地址 std::vector<domain_info*>::iterator it = domain_list_->begin(); for (; it != domain_list_->end(); ++it) { (*it)->set_begin(); acl_dns_lookup(dns, (*it)->get_domain(), dns_result, *it); } while (1) { /* 异步事件循环过程 */ acl_aio_loop(aio); // 如果所有查询过程都完成,则退出异步事件循环过程 if (nresult_ >= domain_list_->size()) { logger("DNS lookup over: %d, %d", (int) domain_list_->size(), (int) nresult_); break; } t = time(NULL); if (t - last_signal >= 1) { last_signal = t; rpc_signal(NULL); } } /* 显示域名查询结果 */ acl_dns_close(dns); /* 销毁非阻塞句柄 */ acl_aio_free(aio); }
/** * Unpack the result value of a remote, sleepable, interruptible operation * @author Renaud Lottiaux * * @param desc The RPC descriptor to get the result from. * @param res Pointer to store the result. * @param size Size of the result. * * @return 0 in case of success, or negative error code. */ int unpack_remote_sleep_res(struct rpc_desc *desc, void *res, size_t size) { int err, flags; flags = RPC_FLAGS_INTR; for (;;) { err = rpc_unpack(desc, flags, res, size); switch (err) { case RPC_EOK: return 0; case RPC_EINTR: BUG_ON(flags != RPC_FLAGS_INTR); rpc_signal(desc, SIGINT); /* * We do not need to explicitly receive SIGACK, * since the server will return the result * anyway. */ flags = 0; break; case RPC_EPIPE: return -EPIPE; default: BUG(); } } return err; }
bool pop3_client::pop3_retr(acl::socket_stream& conn, const std::vector<size_t>& size_list) { if (recv_limit_ == 0) return true; if (recv_limit_ < 0 || recv_limit_ > (int) size_list.size()) meter_.recved_limit = size_list.size(); else meter_.recved_limit = recv_limit_; recv_begin_ = time(NULL); time_t now, inter; for (size_t i = 1; i <= meter_.recved_limit; i++) { if (pop3_retr_one(conn, i) == false) return false; time(&now); inter = now - recv_begin_; if (inter > 0) meter_.recved_speed = meter_.recved_size / inter; UP_CTX* up = new UP_CTX; up->curr = i; up->total = meter_.recved_limit; up->msg.format("接收邮件(%d/%d), 收到 %d 字节, %d 字节/秒", (int) meter_.recved_count, (int) meter_.recved_limit, (int) meter_.recved_size, (int) meter_.recved_speed); rpc_signal(up); } return true; }
bool pop3_client::pop3_retr_one(acl::socket_stream& conn, size_t idx) { if (conn.format("RETR %d\r\n", idx) == -1) { logger_error("send RETR %d to pop3 server(%s) error %s, " "user: %s", pop3_ip_.c_str(), idx, acl::last_serror(), auth_account_.c_str()); return false; } acl::string line; if (conn.gets(line) == false) { logger_error("gets RETR's reply from server(%s) error(%s), " "user: %s", pop3_ip_.c_str(), acl::last_serror(), auth_account_.c_str()); return false; } if (line.ncompare("+OK", 3, false) != 0) { logger_error("RETR's reply(%s) error from server %s, user: %s", line.c_str(), pop3_ip_.c_str(), auth_account_.c_str()); return false; } time_t last, now; time(&last); static int __count = 0; __count++; acl::string filepath; filepath.format("%d.eml", __count); acl::ofstream out; if (resv_save_ && out.open_write(filepath) == false) { logger_error("open file %s error %s", filepath.c_str(), acl::last_serror()); return false; } while (true) { line.clear(); if (conn.gets(line, false) == false) { logger_error("gets mail data error(%s) from server %s, " "user: %s, idx: %d", acl::last_serror(), pop3_ip_.c_str(), auth_account_.c_str(), idx); return false; } if (line == ".\n" || line == ".\r\n") break; if (out.write(line) == -1) logger_error("write to %s error %s, %d", filepath.c_str(), acl::last_serror()); meter_.recved_size += line.length(); time(&now); if (now - last >= 1) { UP_CTX* up = new UP_CTX; up->curr = meter_.recved_count; up->total = meter_.recved_limit; meter_.recved_speed = meter_.recved_size / (int) (now - recv_begin_); up->msg.format("接收邮件(%d/%d), 收到 %d 字节, " "%d 字节/秒", (int) meter_.recved_count, (int) meter_.recved_limit, (int) meter_.recved_size, (int) meter_.recved_speed); rpc_signal(up); time(&last); } } meter_.recved_count++; return true; }
void pop3_client::rpc_run() { UP_CTX* up; struct timeval begin, last, now; gettimeofday(&begin, NULL); ////////////////////////////////////////////////////////////////// // 域名解析过程 gettimeofday(&last, NULL); if (get_ip() == false) { up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("解析 pop3 域名:%s 失败!", pop3_addr_.c_str()); rpc_signal(up); return; } gettimeofday(&now, NULL); meter_.pop3_nslookup_elapsed = util::stamp_sub(&now, &last); acl::string pop3_addr; pop3_addr.format("%s:%d", pop3_ip_.c_str(), pop3_port_); ////////////////////////////////////////////////////////////////// // 远程连接 SMTP 服务器 up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("连接 POP3 服务器 ..."); rpc_signal(up); acl::socket_stream conn; if (conn.open(pop3_addr.c_str(), connect_timeout_, rw_timeout_) == false) { logger_error("connect pop3 server(%s) error", pop3_addr); up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("连接 pop3 服务器:%s 失败!", pop3_addr.c_str()); rpc_signal(up); return; } gettimeofday(&now, NULL); meter_.pop3_connect_elapsed = util::stamp_sub(&now, &last); ////////////////////////////////////////////////////////////////// // 获得 POP3 服务器的欢迎信息 up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("接收 POP3 服务器欢迎信息(连接耗时 %.2f 毫秒) ...", meter_.pop3_connect_elapsed); rpc_signal(up); gettimeofday(&last, NULL); if (pop3_get_banner(conn) == false) return; gettimeofday(&now, NULL); meter_.pop3_banner_elapsed = util::stamp_sub(&now, &last); up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("获得 banner 耗时 %.2f 毫秒,开始认证账号信息 ...", meter_.pop3_banner_elapsed); rpc_signal(up); ////////////////////////////////////////////////////////////////// // 认证用户的身份 gettimeofday(&last, NULL); if (pop3_auth(conn, auth_account_.c_str(), auth_passwd_.c_str()) == false) { return; } gettimeofday(&now, NULL); meter_.pop3_auth_elapsed = util::stamp_sub(&now, &last); up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("用户认证成功(耗时 %.2f 毫秒)", meter_.pop3_auth_elapsed); rpc_signal(up); ////////////////////////////////////////////////////////////////// // uidl 用户收件箱的邮件列表 up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("列用户收件箱邮件(UIDL) ..."); rpc_signal(up); std::vector<acl::string> uidl_list; gettimeofday(&last, NULL); if (pop3_uidl(conn, uidl_list) == false) return; gettimeofday(&now, NULL); meter_.pop3_uidl_elapsed = util::stamp_sub(&now, &last); up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("用户收件箱邮件列表结束(耗时 %.2f 毫秒)", meter_.pop3_uidl_elapsed); rpc_signal(up); ////////////////////////////////////////////////////////////////// // LIST 用户收件箱邮件列表 up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("列用户收件箱邮件尺寸(LIST) ..."); rpc_signal(up); std::vector<size_t> size_list_; gettimeofday(&last, NULL); if (pop3_list(conn, size_list_) == false) { logger_error("pop3_list failed for %s", auth_account_.c_str()); return; } gettimeofday(&now, NULL); meter_.pop3_list_elapsed = util::stamp_sub(&now, &last); up = new UP_CTX; up->curr = 0; up->total = 0; up->msg.format("列用户收件箱邮件尺寸(LIST) 耗时 %.2f", meter_.pop3_list_elapsed); rpc_signal(up); ////////////////////////////////////////////////////////////////// // 收取用户收件里的邮件 up = new UP_CTX; up->curr = 0; up->total = size_list_.size(); up->msg.format("开始接收收件箱邮件 ..."); rpc_signal(up); gettimeofday(&last, NULL); if (pop3_retr(conn, size_list_) == false) { logger_error("pop3_retr failed for %s", auth_account_.c_str()); return; } gettimeofday(&now, NULL); meter_.pop3_recv_elapsed = util::stamp_sub(&now, &last); up = new UP_CTX; up->curr = 0; up->total = size_list_.size(); up->msg.format("接收收件箱邮件完成,耗时 %0.2f", meter_.pop3_recv_elapsed); rpc_signal(up); ////////////////////////////////////////////////////////////////// // 退出邮箱 gettimeofday(&last, NULL); pop3_quit(conn); gettimeofday(&now, NULL); meter_.pop3_quit_elapsed = util::stamp_sub(&now, &last); ////////////////////////////////////////////////////////////////// // 统计总共耗费的时间 gettimeofday(&now, NULL); meter_.pop3_total_elapsed = util::stamp_sub(&now, &begin); up = new UP_CTX; up->curr = 0; up->total = size_list_.size(); up->msg.format("收件过程共耗时 %0.2f", meter_.pop3_recv_elapsed); rpc_signal(up); }