/* eventcb for bufferevent. For the purpose of simplicity and readability of the example program, we omitted the certificate and peer verification. After SSL/TLS handshake is over, initialize nghttp2 library session, and send client connection header. Then send HTTP request. */ static void eventcb(struct bufferevent *bev, short events, void *ptr) { http2_session_data *session_data = (http2_session_data*)ptr; if(events & BEV_EVENT_CONNECTED) { int fd = bufferevent_getfd(bev); int val = 1; fprintf(stderr, "Connected\n"); setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); initialize_nghttp2_session(session_data); send_client_connection_header(session_data); submit_request(session_data); if(session_send(session_data) != 0) { delete_http2_session_data(session_data); } return; } if(events & BEV_EVENT_EOF) { warnx("Disconnected from the remote host"); } else if(events & BEV_EVENT_ERROR) { warnx("Network error"); } else if(events & BEV_EVENT_TIMEOUT) { warnx("Timeout"); } delete_http2_session_data(session_data); }
/* * Handle socket events, such as connection failure or success. * - BEV_EVENT_ERROR - network is unreachable * - BEV_EVENT_ERROR+READING - connection refused or connection timed out * - BEV_EVENT_TIMEOUT+READING - write timeout, if activated by * bufferevent_set_timeouts */ static void session_eventcb(struct bufferevent *bev, short what, void *thunk) { struct session *session = thunk; switch (what & ~(BEV_EVENT_READING|BEV_EVENT_WRITING)) { case BEV_EVENT_CONNECTED: session_send(session); return; case BEV_EVENT_EOF: bufferevent_disable(bev, EV_READ|EV_WRITE); if (session->completed) target_mark(session->t, session->seq, '.'); else target_mark(session->t, session->seq, '%'); break; case BEV_EVENT_ERROR: bufferevent_disable(bev, EV_READ|EV_WRITE); target_mark(session->t, session->seq, '#'); break; case BEV_EVENT_TIMEOUT: target_mark(session->t, session->seq, '?'); break; } session_free(session); }
static void on_connected(int32_t fd,int32_t err,void *ud) { if(fd >= 0 && err == 0) { engine *e = (engine*)ud; stream_socket_ *h = new_stream_socket(fd); engine_associate(e,h,transfer_finish); struct session *s = session_new(h); session_send(s,65535); } else if(err == ETIMEDOUT) { printf("connect timeout\n"); } }
void on_connect(kn_fd_t s,struct kn_sockaddr *remote,void *ud,int err) { kn_proactor_t p = (kn_proactor_t)ud; if(s){ printf("connect ok\n"); struct session *session = calloc(1,sizeof(*session)); session->s = s; kn_fd_setud(s,session); kn_proactor_bind(p,s,transfer_finish); session_send(session,send_size); }else{ printf("connect failed\n"); } }
/* writecb for bufferevent. To greaceful shutdown after sending or receiving GOAWAY, we check the some conditions on the nghttp2 library and output buffer of bufferevent. If it indicates we have no business to this session, tear down the connection. If the connection is not going to shutdown, we call session_send() to process pending data in the output buffer. This is necessary because we have a threshold on the buffer size to avoid too much buffering. See send_callback(). */ static void writecb(struct bufferevent *bev, void *ptr) { http2_session_data *session_data = (http2_session_data *)ptr; if (evbuffer_get_length(bufferevent_get_output(bev)) > 0) { return; } if (nghttp2_session_want_read(session_data->session) == 0 && nghttp2_session_want_write(session_data->session) == 0) { delete_http2_session_data(session_data); return; } if (session_send(session_data) != 0) { delete_http2_session_data(session_data); return; } }
/* Read the data in the bufferevent and feed them into nghttp2 library function. Invocation of nghttp2_session_mem_recv() may make additional pending frames, so call session_send() at the end of the function. */ static int session_recv(http2_session_data *session_data) { int rv; struct evbuffer *input = bufferevent_get_input(session_data->bev); size_t datalen = evbuffer_get_length(input); unsigned char *data = evbuffer_pullup(input, -1); rv = nghttp2_session_mem_recv(session_data->session, data, datalen); if(rv < 0) { warnx("Fatal error: %s", nghttp2_strerror(rv)); return -1; } evbuffer_drain(input, rv); if(session_send(session_data) != 0) { return -1; } return 0; }
/* eventcb for bufferevent. For the purpose of simplicity and readability of the example program, we omitted the certificate and peer verification. After SSL/TLS handshake is over, initialize nghttp2 library session, and send client connection header. Then send HTTP request. */ static void eventcb(struct bufferevent *bev, short events, void *ptr) { http2_session_data *session_data = (http2_session_data *)ptr; if (events & BEV_EVENT_CONNECTED) { int fd = bufferevent_getfd(bev); int val = 1; const unsigned char *alpn = NULL; unsigned int alpnlen = 0; SSL *ssl; fprintf(stderr, "Connected\n"); ssl = bufferevent_openssl_get_ssl(session_data->bev); #ifndef OPENSSL_NO_NEXTPROTONEG SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen); #endif /* !OPENSSL_NO_NEXTPROTONEG */ #if OPENSSL_VERSION_NUMBER >= 0x10002000L if (alpn == NULL) { SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); } #endif /* OPENSSL_VERSION_NUMBER >= 0x10002000L */ if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) { fprintf(stderr, "h2 is not negotiated\n"); delete_http2_session_data(session_data); return; } setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val)); initialize_nghttp2_session(session_data); send_client_connection_header(session_data); submit_request(session_data); if (session_send(session_data) != 0) { delete_http2_session_data(session_data); } return; } if (events & BEV_EVENT_EOF) { warnx("Disconnected from the remote host"); } else if (events & BEV_EVENT_ERROR) { warnx("Network error"); } else if (events & BEV_EVENT_TIMEOUT) { warnx("Timeout"); } delete_http2_session_data(session_data); }
/* eventcb for bufferevent */ static void eventcb(struct bufferevent *bev, short events, void *ptr) { http2_session_data *session_data = (http2_session_data *)ptr; if (events & BEV_EVENT_CONNECTED) { const unsigned char *alpn = NULL; unsigned int alpnlen = 0; SSL *ssl; (void)bev; fprintf(stderr, "%s connected\n", session_data->client_addr); ssl = bufferevent_openssl_get_ssl(session_data->bev); SSL_get0_next_proto_negotiated(ssl, &alpn, &alpnlen); #if OPENSSL_VERSION_NUMBER >= 0x10002000L if (alpn == NULL) { SSL_get0_alpn_selected(ssl, &alpn, &alpnlen); } #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L if (alpn == NULL || alpnlen != 2 || memcmp("h2", alpn, 2) != 0) { fprintf(stderr, "%s h2 is not negotiated\n", session_data->client_addr); delete_http2_session_data(session_data); return; } initialize_nghttp2_session(session_data); if (send_server_connection_header(session_data) != 0 || session_send(session_data) != 0) { delete_http2_session_data(session_data); return; } return; } if (events & BEV_EVENT_EOF) { fprintf(stderr, "%s EOF\n", session_data->client_addr); } else if (events & BEV_EVENT_ERROR) { fprintf(stderr, "%s network error\n", session_data->client_addr); } else if (events & BEV_EVENT_TIMEOUT) { fprintf(stderr, "%s timeout\n", session_data->client_addr); } delete_http2_session_data(session_data); }
/* Read the data in the bufferevent and feed them into nghttp2 library function. Invocation of nghttp2_session_mem_recv() may make additional pending frames, so call session_send() at the end of the function. */ static int session_recv(http2_session_data *session_data) { ssize_t readlen; struct evbuffer *input = bufferevent_get_input(session_data->bev); size_t datalen = evbuffer_get_length(input); unsigned char *data = evbuffer_pullup(input, -1); readlen = nghttp2_session_mem_recv(session_data->session, data, datalen); if (readlen < 0) { warnx("Fatal error: %s", nghttp2_strerror((int)readlen)); return -1; } if (evbuffer_drain(input, (size_t)readlen) != 0) { warnx("Fatal error: evbuffer_drain failed"); return -1; } if (session_send(session_data) != 0) { return -1; } return 0; }
int32_t _send_direct( struct iolayer * self, struct session_manager * manager, struct task_send * task ) { int32_t rc = -1; struct session * session = session_manager_get( manager, task->id ); if ( likely(session != NULL) ) { // 数据统一改造 char * buffer = task->buf; uint32_t nbytes = task->nbytes; if ( self->transform != NULL ) { buffer = self->transform( self->context, task->buf, &nbytes ); } if ( buffer != NULL ) { rc = session_send( session, buffer, nbytes ); // 销毁改造后的数据 if ( buffer != task->buf ) { free( buffer ); } } } else { syslog(LOG_WARNING, "%s(SID=%ld) failed, the Session is invalid .", __FUNCTION__, task->id ); } if ( task->isfree != 0 ) { // 指定底层释放 free( task->buf ); } return rc; }
/* readcb for bufferevent. Here we get the data from the input buffer of bufferevent and feed them to nghttp2 library. This may invoke nghttp2 callbacks. It may also queues the frame in nghttp2 session context. To send them, we call session_send() in the end. */ static void readcb(struct bufferevent *bev, void *ptr) { http2_session_data *session_data = (http2_session_data *)ptr; ssize_t readlen; struct evbuffer *input = bufferevent_get_input(bev); size_t datalen = evbuffer_get_length(input); unsigned char *data = evbuffer_pullup(input, -1); readlen = nghttp2_session_mem_recv(session_data->session, data, datalen); if (readlen < 0) { warnx("Fatal error: %s", nghttp2_strerror((int)readlen)); delete_http2_session_data(session_data); return; } if (evbuffer_drain(input, (size_t)readlen) != 0) { warnx("Fatal error: evbuffer_drain failed"); delete_http2_session_data(session_data); return; } if (session_send(session_data) != 0) { delete_http2_session_data(session_data); return; } }
int _zfp_transport_thread(void *param) { zfp_transport_t *transport = (zfp_transport_t*)param; if (transport == NULL) { LOG_ERROR("Invalid transport"); return 0; } FILE *file = (FILE*)transport->file_handle; if (file == NULL) { LOG_ERROR("Invalid file handle"); return 0; } // TODO: mv zfp_head_t to zfp_transport_t zfp_head_t *head_resp = NULL; if (zfp_head_new(&head_resp) != ZISS_OK || head_resp == NULL) { LOG_ERROR("Fail to new zfp head"); return 0; } head_resp->session = session_getid(transport->session); head_resp->seq = transport->seq++; head_resp->cmd = ZFP_CMD_TRANSPORT; head_resp->resp_code = ZFP_REP_ERROR; head_resp->csize = 0; char *buf = transport->buf + sizeof(zfp_head_t); int buf_len = transport->buf_len; int i = 0; LOG_INFO("transport[%p] starting...", transport); while (!transport->is_to_exit) { int ret = ZISS_OK; memset(buf, 0, buf_len); size_t read_size = fread(buf, 1, buf_len, file); if (read_size > 0) { head_resp->resp_code = ZFP_REP_DATA; } else { if (feof(file)) { head_resp->resp_code = ZFP_REP_DATAEND; const char *str = "data end"; read_size = strlen(str) + 1; strncpy(buf, str, read_size); } else { head_resp->resp_code = ZFP_REP_ERROR; const char *str = "error"; read_size = strlen(str) + 1; strncpy(buf, str, read_size); } ret = ZISS_ERROR; } head_resp->csize = read_size; head_resp->chksum = zfp_head_get_chksum(head_resp); memcpy(transport->buf, head_resp, sizeof(zfp_head_t)); int outlen = 0; //LOG_INFO("transport[0x%x] send resp_code %d", (unsigned int)transport, head_resp->resp_code); if (session_send(transport->session, transport->buf, sizeof(zfp_head_t) + read_size, &outlen) == ZISS_ERROR) { LOG_INFO("transport[%p] send resp_code %d failed.", transport, head_resp->resp_code); break; } LOG_INFO("transport[%p] send resp_code %d ok", transport, head_resp->resp_code); if (ret == ZISS_ERROR) break; if (head_resp->resp_code == ZFP_REP_DATAEND) break; } zfp_head_delete(head_resp); LOG_INFO("transport[%p] end.", transport); return 0; }
int send_message(CConceptClient *OWNER, AnsiString SENDER_NAME, int MESSAGE_ID, AnsiString MESSAGE_TARGET, AnsiString& MESSAGE_DATA, SOCKET CLIENT_SOCKET, char *REMOTE_PUBLIC_KEY, PROGRESS_API notify_parent, bool idle_call) { INTEGER res = 0; char *buffer = 0; int in_content_size = 0; FILE *in = 0; int file_buffer_size = 0; bool buferize = REMOTE_PUBLIC_KEY ? true : false; int is_realtime = 0; if ((MESSAGE_ID == 0x1001) && (MESSAGE_TARGET == (char *)"350")) { MESSAGE_ID = 0x110; MESSAGE_TARGET = ""; } char *base_ptr = SerializeBuffer(OWNER->RTSOCKET, &buffer, &in_content_size, &SENDER_NAME, MESSAGE_ID, &MESSAGE_TARGET, &MESSAGE_DATA, buferize, &in, &file_buffer_size, (!REMOTE_PUBLIC_KEY) || (OWNER->is_http), &is_realtime); int size_n; if ((REMOTE_PUBLIC_KEY) && (!OWNER->is_http)) { // criptez query-ul ... int out_content_size = (in_content_size / 16 + 1) * 16 + 5; char *out_content = new char[out_content_size]; int encrypt_result = AES_encrypt(buffer, in_content_size, out_content, out_content_size, REMOTE_PUBLIC_KEY, 16, !is_realtime); if (!encrypt_result) { delete[] out_content; return 0; } int size = encrypt_result; size_n = htonl(size); session_send(OWNER, CLIENT_SOCKET, (char *)&size_n, sizeof(int), 0); //----------------------------------------// if ((size >= BIG_MESSAGE) && (notify_parent)) { // notify big message ! notify_parent(-1, 1, idle_call); int chunks = size / CHUNK_SIZE; if (size % CHUNK_SIZE) chunks++; for (int i = 0; i < chunks; i++) { int chunk_size = (i < chunks - 1) ? CHUNK_SIZE : size % CHUNK_SIZE; res = session_send(OWNER, CLIENT_SOCKET, out_content + (i * CHUNK_SIZE), chunk_size, 0); if (res != chunk_size) { notify_parent(-1, 2, idle_call); break; } notify_parent((int)(((double)(i * CHUNK_SIZE + res) / size) * 100), 0, idle_call); } //notify_parent(101, 0, idle_call); // done big message ! } else res = session_send(OWNER, CLIENT_SOCKET, out_content, size, 0); delete[] out_content; } else { // trimit dimensiunea mai intai ... size_n = htonl(in_content_size + file_buffer_size); bool big_message = false; int total_sent = 0; if ((in_content_size + file_buffer_size >= BIG_MESSAGE) && (notify_parent)) { if (!OWNER->is_http) session_send(OWNER, CLIENT_SOCKET, (char *)&size_n, sizeof(int), 0); // notify big message ! big_message = true; notify_parent(-1, 1, idle_call); int chunks = in_content_size / CHUNK_SIZE; if (in_content_size % CHUNK_SIZE) chunks++; for (int i = 0; i < chunks; i++) { int chunk_size = (i < chunks - 1) ? CHUNK_SIZE : in_content_size % CHUNK_SIZE; int to_send = chunk_size; res = session_send(OWNER, CLIENT_SOCKET, buffer + (i * CHUNK_SIZE), chunk_size, 0); if (res != to_send) { notify_parent(-1, 2, idle_call); if (in) { fclose(in); in = 0; } break; } total_sent = i * CHUNK_SIZE + res; notify_parent((int)(((double)(total_sent) / (in_content_size + file_buffer_size)) * 100), 0, idle_call); } if (!in) notify_parent(101, 0, idle_call); // done big message ! } else { res = session_send(OWNER, CLIENT_SOCKET, /*buffer*/ base_ptr, in_content_size + sizeof(int), 0, is_realtime); } if (in) { int r = 0; char *file_buf = new char[RBUF_SIZE]; int chunk_size = 0; do { chunk_size = fread(file_buf, 1, RBUF_SIZE, in); if (chunk_size > 0) { res = session_send(OWNER, CLIENT_SOCKET, file_buf, chunk_size, 0); if (res != chunk_size) { if (big_message) notify_parent(-1, 2, idle_call); break; } total_sent += res; if (big_message) notify_parent((int)(((double)(total_sent) / (in_content_size + file_buffer_size)) * 100), 0, idle_call); } } while (chunk_size == RBUF_SIZE); delete[] file_buf; fclose(in); in = NULL; if (big_message) notify_parent(101, 0, idle_call); } } if (base_ptr) delete[] base_ptr; // BUG: buffer=base_ptr+sizeof(long). Cannot delete buffer ! //delete[] buffer; return 0; }