static evhtp_res set_my_connection_handlers(evhtp_connection_t * conn, void * arg) { struct timeval tick; struct ev_token_bucket_cfg * tcfg = NULL; evhtp_set_hook(&conn->hooks, evhtp_hook_on_header, print_kv, "foo"); evhtp_set_hook(&conn->hooks, evhtp_hook_on_headers, print_kvs, "bar"); evhtp_set_hook(&conn->hooks, evhtp_hook_on_path, print_path, "baz"); evhtp_set_hook(&conn->hooks, evhtp_hook_on_read, print_data, "derp"); evhtp_set_hook(&conn->hooks, evhtp_hook_on_new_chunk, print_new_chunk_len, NULL); evhtp_set_hook(&conn->hooks, evhtp_hook_on_chunk_complete, print_chunk_complete, NULL); evhtp_set_hook(&conn->hooks, evhtp_hook_on_chunks_complete, print_chunks_complete, NULL); /* evhtp_set_hook(&conn->hooks, evhtp_hook_on_hostname, print_hostname, NULL); */ if (bw_limit > 0) { tick.tv_sec = 0; tick.tv_usec = 500 * 100; tcfg = ev_token_bucket_cfg_new(bw_limit, bw_limit, bw_limit, bw_limit, &tick); bufferevent_set_rate_limit(conn->bev, tcfg); } evhtp_set_hook(&conn->hooks, evhtp_hook_on_request_fini, test_fini, tcfg); return EVHTP_RES_OK; }
bool NwConnection::setRateLimit(size_t rr, size_t rb, size_t wr, size_t wb, float sec) { if (!mBackend.backend) { return false; } if (mBackend.rate) { bufferevent_set_rate_limit(mBackend.backend, 0); ev_token_bucket_cfg_free(mBackend.rate); } timeval tv; tv.tv_sec = static_cast<long>(sec); tv.tv_usec = static_cast<long>((sec - tv.tv_sec) * 1000000); mBackend.rate = ev_token_bucket_cfg_new(rr, rb, wr, wb, &tv); if (!mBackend.rate) { return false; } bufferevent_set_rate_limit(mBackend.backend, mBackend.rate); return true; }
bool NwConnection::setRateLimit(size_t rr, size_t rb, size_t wr, size_t wb) { if (!mBackend.backend) { return false; } if (mBackend.rate) { bufferevent_set_rate_limit(mBackend.backend, 0); ev_token_bucket_cfg_free(mBackend.rate); } mBackend.rate = ev_token_bucket_cfg_new(rr, rb, wr, wb, 0); if (!mBackend.rate) { return false; } bufferevent_set_rate_limit(mBackend.backend, mBackend.rate); return true; }
static int test_ratelimiting(void) { struct event_base *base; struct sockaddr_in sin; struct evconnlistener *listener; struct sockaddr_storage ss; ev_socklen_t slen; struct bufferevent **bevs; struct client_state *states; struct bufferevent_rate_limit_group *group = NULL; int i; struct timeval tv; ev_uint64_t total_received; double total_sq_persec, total_persec; double variance; double expected_total_persec = -1.0, expected_avg_persec = -1.0; int ok = 1; struct event_config *base_cfg; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_addr.s_addr = htonl(0x7f000001); /* 127.0.0.1 */ sin.sin_port = 0; /* unspecified port */ if (0) event_enable_debug_mode(); base_cfg = event_config_new(); #ifdef _WIN32 if (cfg_enable_iocp) { evthread_use_windows_threads(); event_config_set_flag(base_cfg, EVENT_BASE_FLAG_STARTUP_IOCP); } #endif base = event_base_new_with_config(base_cfg); listener = evconnlistener_new_bind(base, echo_listenercb, base, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE, -1, (struct sockaddr *)&sin, sizeof(sin)); slen = sizeof(ss); if (getsockname(evconnlistener_get_fd(listener), (struct sockaddr *)&ss, &slen) < 0) { perror("getsockname"); return 1; } if (cfg_connlimit > 0) { conn_bucket_cfg = ev_token_bucket_cfg_new( cfg_connlimit, cfg_connlimit * 4, cfg_connlimit, cfg_connlimit * 4, &cfg_tick); assert(conn_bucket_cfg); } if (cfg_grouplimit > 0) { group_bucket_cfg = ev_token_bucket_cfg_new( cfg_grouplimit, cfg_grouplimit * 4, cfg_grouplimit, cfg_grouplimit * 4, &cfg_tick); group = ratelim_group = bufferevent_rate_limit_group_new( base, group_bucket_cfg); expected_total_persec = cfg_grouplimit; expected_avg_persec = cfg_grouplimit / cfg_n_connections; if (cfg_connlimit > 0 && expected_avg_persec > cfg_connlimit) expected_avg_persec = cfg_connlimit; if (cfg_min_share >= 0) bufferevent_rate_limit_group_set_min_share( ratelim_group, cfg_min_share); } if (expected_avg_persec < 0 && cfg_connlimit > 0) expected_avg_persec = cfg_connlimit; if (expected_avg_persec > 0) expected_avg_persec /= seconds_per_tick; if (expected_total_persec > 0) expected_total_persec /= seconds_per_tick; bevs = calloc(cfg_n_connections, sizeof(struct bufferevent *)); states = calloc(cfg_n_connections, sizeof(struct client_state)); for (i = 0; i < cfg_n_connections; ++i) { bevs[i] = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE|BEV_OPT_THREADSAFE); assert(bevs[i]); bufferevent_setcb(bevs[i], discard_readcb, loud_writecb, write_on_connectedcb, &states[i]); bufferevent_enable(bevs[i], EV_READ|EV_WRITE); bufferevent_socket_connect(bevs[i], (struct sockaddr *)&ss, slen); } tv.tv_sec = cfg_duration - 1; tv.tv_usec = 995000; event_base_loopexit(base, &tv); event_base_dispatch(base); ratelim_group = NULL; /* So no more responders get added */ for (i = 0; i < cfg_n_connections; ++i) { bufferevent_free(bevs[i]); } evconnlistener_free(listener); /* Make sure no new echo_conns get added to the group. */ ratelim_group = NULL; /* This should get _everybody_ freed */ while (n_echo_conns_open) { printf("waiting for %d conns\n", n_echo_conns_open); tv.tv_sec = 0; tv.tv_usec = 300000; event_base_loopexit(base, &tv); event_base_dispatch(base); } if (group) bufferevent_rate_limit_group_free(group); total_received = 0; total_persec = 0.0; total_sq_persec = 0.0; for (i=0; i < cfg_n_connections; ++i) { double persec = states[i].received; persec /= cfg_duration; total_received += states[i].received; total_persec += persec; total_sq_persec += persec*persec; printf("%d: %f per second\n", i+1, persec); } printf(" total: %f per second\n", ((double)total_received)/cfg_duration); if (expected_total_persec > 0) { double diff = expected_total_persec - ((double)total_received/cfg_duration); printf(" [Off by %lf]\n", diff); if (cfg_grouplimit_tolerance > 0 && fabs(diff) > cfg_grouplimit_tolerance) { fprintf(stderr, "Group bandwidth out of bounds\n"); ok = 0; } } printf(" average: %f per second\n", (((double)total_received)/cfg_duration)/cfg_n_connections); if (expected_avg_persec > 0) { double diff = expected_avg_persec - (((double)total_received)/cfg_duration)/cfg_n_connections; printf(" [Off by %lf]\n", diff); if (cfg_connlimit_tolerance > 0 && fabs(diff) > cfg_connlimit_tolerance) { fprintf(stderr, "Connection bandwidth out of bounds\n"); ok = 0; } } variance = total_sq_persec/cfg_n_connections - total_persec*total_persec/(cfg_n_connections*cfg_n_connections); printf(" stddev: %f per second\n", sqrt(variance)); if (cfg_stddev_tolerance > 0 && sqrt(variance) > cfg_stddev_tolerance) { fprintf(stderr, "Connection variance out of bounds\n"); ok = 0; } event_base_free(base); free(bevs); free(states); return ok ? 0 : 1; }
bool CNetService::Initialize( Foundation::LogService::ILog::Ptr log, unsigned int recv_size ) { DXM_COMPONENT_LOG.set_log(log); DXM_NDC("NetService::Initialize"); boost::unique_lock<boost::shared_mutex> lock(running_mutex_); if(is_running_) { DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_ERROR, "net service is initialized"); return false; } if(recv_size == 0) { DXM_COMPONENT_LOG(DXM_COMPONENT_LOG_LEVEL_ERROR, "recv_size cannot be 0" ); return false; } tls_recv_buffer_.set_default_size(recv_size); #ifdef WIN32 // wsa init WSAData wsaData; if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_ERROR, "net service initialize WSAStartup failed."); return false; } DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_TRACE, "wsastartup ok."); // about thread and lock evthread_use_windows_threads(); DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_TRACE, "evthread_set ok."); // get count of processors SYSTEM_INFO sysInfo; GetSystemInfo(&sysInfo); DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_TRACE, "getsysteminfo ok. numberofprocessors: %u.", sysInfo.dwNumberOfProcessors); // event config ev_config_ = event_config_new(); event_config_set_flag(ev_config_, EVENT_BASE_FLAG_STARTUP_IOCP); event_config_set_num_cpus_hint(ev_config_, sysInfo.dwNumberOfProcessors); DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_TRACE, "event_config_set ok."); #else // about thread and lock evthread_use_pthreads(); // event config ev_config_ = event_config_new(); event_config_set_flag(ev_config_, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST); DXM_COMPONENT_LOG(DXM_COMPONENT_LOG_LEVEL_TRACE, "event_config_set ok."); #endif // event base ev_base_ = event_base_new_with_config(ev_config_); DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_TRACE, "event_base_new ok."); // tv timeval tv; // ev token bucket cfg tv.tv_sec = 0; tv.tv_usec = 0; ev_t_bucket_cfg_ = ev_token_bucket_cfg_new(EV_RATE_LIMIT_MAX, EV_RATE_LIMIT_MAX, 1024, 1024, &tv); DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_TRACE, "ev_token_bucket_cfg_new ok."); // set an event tv.tv_sec = 1; tv.tv_usec = 0; ev_ = evtimer_new(ev_base_, defaultEventFunc, this); event_add(ev_, &tv); DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_TRACE, "event_add timer ok."); // run loop callback pthread_create(&loop_thread_, 0, loopThreadStartFunc, this); DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_TRACE, "main thread create ok."); // start is_running_ = true; DXM_COMPONENT_LOG( DXM_COMPONENT_LOG_LEVEL_INFO, "Initialize Finish."); return true; }
int main () { int sockfd; struct bufferevent *p_event; struct sockaddr_in addr; int cc; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); if (inet_pton(AF_INET, SVRADDR, &addr.sin_addr) <= 0) { printf("inet_pton"); exit(1); } if ((p_base = event_base_new()) == NULL) { printf("event_base_new "); return 1; } /* we do not need invoke socket function to create socket */ if ((p_event = bufferevent_socket_new(p_base, -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_DEFER_CALLBACKS)) == NULL) { printf("bufferevent_socket_new "); return 1; } /* client actually connecte to server at this time. */ if ((sockfd = bufferevent_socket_connect(p_event, (struct sockaddr *) &addr, sizeof(addr))) < 0) { printf("bufferevent_socket_connect "); return 1; } /* EV_WRITE is default enabled, EV_READ is default disabled */ /* So If we disable READ, evbuffer callback will not be added to base (read and write) */ bufferevent_setcb(p_event, buff_input_cb, buff_output_cb, NULL, p_base); bufferevent_enable(p_event, EV_WRITE | EV_READ); /* you should not free cfg immediately, after call bufferevent_set_rate_limit. */ /* you should not set the burst rate little than average rate */ struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new (1, 1, 10240, 10240, NULL); assert (NULL != cfg); /* If Server send N bytes, every time, * read callback will be invoked when 2 bytes read to evbuffer. */ cc = bufferevent_set_rate_limit (p_event, cfg); assert (cc == 0); #if 0 struct bufferevent *bev=bufferevent_socket_new (p_base, bufferevent_getfd(p_event), BEV_OPT_DEFER_CALLBACKS); assert (NULL != bev); bufferevent_set_rate_limit (bev, cfg); bufferevent_setcb(bev, buff_input_cb, NULL, NULL, NULL); bufferevent_enable(bev, EV_WRITE | EV_READ); #endif struct event *ev = event_new (p_base, SIGINT, EV_SIGNAL | EV_PERSIST, sigint, NULL); event_add (ev, NULL); event_base_dispatch(p_base); ev_token_bucket_cfg_free (cfg); return 0; }
int main () { int sockfd; struct bufferevent *p_event; struct sockaddr_in addr; int cc; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(PORT); if (inet_pton(AF_INET, SVRADDR, &addr.sin_addr) <= 0) { printf("inet_pton"); exit(1); } if ((p_base = event_base_new()) == NULL) { printf("event_base_new "); return 1; } /* we do not need invoke socket function to create socket */ if ((p_event = bufferevent_socket_new(p_base, -1, BEV_OPT_CLOSE_ON_FREE)) == NULL) { printf("bufferevent_socket_new "); return 1; } /* client actually connecte to server at this time. */ if ((sockfd = bufferevent_socket_connect(p_event, (struct sockaddr *) &addr, sizeof(addr))) < 0) { printf("bufferevent_socket_connect "); return 1; } /* EV_WRITE is default enabled, EV_READ is default disabled */ /* So If we disable READ, evbuffer callback will not be added to base (read and write) */ bufferevent_setcb(p_event, buff_input_cb, NULL, NULL, p_base); bufferevent_enable(p_event, EV_WRITE | EV_READ); /* you should not free cfg immediately, after call bufferevent_set_rate_limit. */ /* you should not set the burst rate little than average rate */ struct ev_token_bucket_cfg *cfg = ev_token_bucket_cfg_new (EV_RATE_LIMIT_MAX, EV_RATE_LIMIT_MAX, 1, 1, NULL); assert (NULL != cfg); /* If Server send N bytes, every time, * read callback will be invoked when 2 bytes read to evbuffer. */ cc = bufferevent_set_rate_limit (p_event, cfg); // assert (cc == 0); /* this is the defauly value EV_SSIZE_MAX, 0x7FFFFFFF */ ev_ssize_t size = bufferevent_get_read_limit (p_event); printf ("bufferevent read limit 0x%x\n", size); /* 2, average rate */ size = bufferevent_get_write_limit (p_event); printf ("bufferevent write limit 0x%x\n", size); /* 1, average rate */ event_base_dispatch(p_base); ev_token_bucket_cfg_free (cfg); return 0; }