static protocol_t * protocol_ssl_accept(protocol_t * p, void *options) { protocol_t *newp; struct sockaddr_in remote; socklen_t addrlen; int ret; ssl_private_t *ssl_p = (ssl_private_t *) p->_protocol_p; ssl_private_t *new_ssl_p; struct sockaddr name; char hostname[128]; flowop_options_t *flowop_options = (flowop_options_t *) options; BIO *sbio; newp = protocol_ssl_new(); new_ssl_p = (ssl_private_t *) newp->_protocol_p; addrlen = (socklen_t) sizeof (remote); uperf_debug("ssl - ssl obj waiting for accept\n"); newp->fd = accept(p->fd, (struct sockaddr *) &remote, &addrlen); if (newp->fd < 0) { uperf_log_msg(UPERF_LOG_ERROR, errno, "accept"); return (NULL); } if (getnameinfo((const struct sockaddr *) & remote, addrlen, hostname, sizeof (hostname), NULL, 0, 0) == 0) { uperf_debug("ssl - Connection from %s:%d\n", hostname, SOCK_PORT(remote)); strlcpy(newp->host, hostname, sizeof (newp->host)); newp->port = SOCK_PORT(remote); } if (flowop_options) { if ((load_engine(flowop_options->engine)) == -1) { uperf_info( "ssl - Engine %s does NOT exist! Using the default OpenSSL softtoken", flowop_options->engine); } } sbio = BIO_new_socket(newp->fd, BIO_NOCLOSE); if (!(new_ssl_p->ssl = SSL_new(ctx))) { uperf_log_msg(UPERF_LOG_ERROR, 0, "SSL_new error"); return (NULL); } SSL_set_bio(new_ssl_p->ssl, sbio, sbio); ret = SSL_accept(new_ssl_p->ssl); if (my_ssl_error(new_ssl_p->ssl, ret) == 0) { return (newp); } else { return (0); } }
/* Returns 0 on success */ int uperf_sleep(hrtime_t duration_nsecs) { #ifdef HAVE_NANOSLEEP struct timespec rqtp, rmtp; rqtp.tv_sec = (long) duration_nsecs/1.0e+9; rqtp.tv_nsec = (long) fmod(duration_nsecs, 1.0e+9); if (nanosleep(&rqtp, &rmtp) == -1) { char msg[512]; int saved_errno = errno; if (saved_errno != EINTR) { (void) snprintf(msg, 512, "Error sleeping for %.4fs\n", duration_nsecs*1.0/1.0e+9); uperf_log_msg(UPERF_LOG_ERROR, saved_errno, msg); } return (saved_errno); } return (0); #else if (duration_nsecs/1.0e+6 < 1) return (0); return (poll(NULL, NULL, (int)(duration_nsecs/1.0e+6)) == 0 ? 0 : errno); #endif }
static int say_goodbye(goodbye_stat_t *total, protocol_t *p, int timeout) { goodbye_t g; char msg[GOODBYE_MESSAGE_LEN]; if (recv_goodbye(&g, p, timeout) != UPERF_SUCCESS) { uperf_error("\nError saying goodbye with %s\n", p->host); return (1); } switch (g.msg_type) { case MESSAGE_INFO: (void) snprintf(msg, GOODBYE_MESSAGE_LEN, "[%s] %s", p->host, g.message); uperf_info(msg); break; case MESSAGE_NONE: break; case MESSAGE_ERROR: (void) snprintf(msg, GOODBYE_MESSAGE_LEN, "[%s] %s", p->host, g.message); uperf_log_msg(UPERF_LOG_ERROR, 0, msg); break; case MESSAGE_WARNING: (void) snprintf(msg, GOODBYE_MESSAGE_LEN, "[%s] %s\n", p->host, g.message); uperf_log_msg(UPERF_LOG_WARN, 0, msg); break; } (void) print_goodbye_stat(p->host, &g.gstat); total->elapsed_time = MAX(g.gstat.elapsed_time, total->elapsed_time); total->error += g.gstat.error; total->bytes_xfer += g.gstat.bytes_xfer; total->count += g.gstat.count; return (0); }
int protocol_sctp_write(protocol_t *p, void *buffer, int size, void *options) #if defined(HAVE_SCTP_SENDV) { ssize_t len; struct iovec iov; struct sctp_sendv_spa info; iov.iov_base = buffer; iov.iov_len = size; memset(&info, 0, sizeof(struct sctp_sendv_spa)); if (options) { flowop_options_t *flowops; flowops = (flowop_options_t *) options; info.sendv_sndinfo.snd_sid = flowops->sctp_stream_id; if (FO_SCTP_UNORDERED(flowops)) { info.sendv_sndinfo.snd_flags |= SCTP_UNORDERED; } info.sendv_flags |= SCTP_SEND_SNDINFO_VALID; #ifdef SCTP_PR_SCTP_TTL if (strcasecmp(flowops->sctp_pr_policy, "ttl") == 0) { info.sendv_prinfo.pr_policy = SCTP_PR_SCTP_TTL; info.sendv_prinfo.pr_value = flowops->sctp_pr_value; info.sendv_flags |= SCTP_SEND_PRINFO_VALID; } #endif #ifdef SCTP_PR_SCTP_RTX if (strcasecmp(flowops->sctp_pr_policy, "rtx") == 0) { info.sendv_prinfo.pr_policy = SCTP_PR_SCTP_RTX; info.sendv_prinfo.pr_value = flowops->sctp_pr_value; info.sendv_flags |= SCTP_SEND_PRINFO_VALID; } #endif #ifdef SCTP_PR_SCTP_BUF if (strcasecmp(flowops->sctp_pr_policy, "buf") == 0) { info.sendv_prinfo.pr_policy = SCTP_PR_SCTP_BUF; info.sendv_prinfo.pr_value = flowops->sctp_pr_value; info.sendv_flags |= SCTP_SEND_PRINFO_VALID; } #endif } if ((len = sctp_sendv(p->fd, &iov, 1, NULL, 0, &info, sizeof(struct sctp_sendv_spa), SCTP_SENDV_SPA, 0)) < 0) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot sctp_sendv "); } return (len); }
static int protocol_ssl_listen(protocol_t * p, void *o) { char msg[128]; if (generic_socket(p, AF_INET6, IPPROTO_TCP) != UPERF_SUCCESS) { if (generic_socket(p, AF_INET, IPPROTO_TCP) != UPERF_SUCCESS) { (void) snprintf(msg, 128, "%s: Cannot create socket", "tcp"); uperf_log_msg(UPERF_LOG_ERROR, errno, msg); return (UPERF_FAILURE); } } set_tcp_options(p->fd, (flowop_options_t *)o); return (generic_listen(p, IPPROTO_TCP, o)); }
/* Send a command to all slaves */ static int send_command_to_slaves(uperf_cmd cmd, int value) { int ret = 0; int i; for (i = 0; i < no_slaves; i++) { ret = uperf_send_command(slaves[i], cmd, value); if (ret <= 0) { char msg[128]; (void) snprintf(msg, sizeof (msg), "Could not send command %d to %s:%d ", value, slaves[i]->host, slaves[i]->port); uperf_log_msg(UPERF_LOG_WARN, ret, msg); break; } } return (ret); }
/* ARGSUSED */ static int protocol_sctp_listen(protocol_t *p, void *options) { char msg[128]; if (generic_socket(p, AF_INET6, IPPROTO_SCTP) != UPERF_SUCCESS) { if (generic_socket(p, AF_INET, IPPROTO_SCTP) != UPERF_SUCCESS) { (void) snprintf(msg, 128, "%s: Cannot create socket", "sctp"); uperf_log_msg(UPERF_LOG_ERROR, errno, msg); return (UPERF_FAILURE); } else { set_sctp_options(p->fd, AF_INET, options); } } else { set_sctp_options(p->fd, AF_INET6, options); } return (generic_listen(p, IPPROTO_SCTP, options)); }
static int protocol_ssl_connect(protocol_t * p, void *options) { BIO *sbio; int status; ssl_private_t *ssl_p = (ssl_private_t *) p->_protocol_p; flowop_options_t *flowop_options = (flowop_options_t *) options; uperf_debug("ssl - Connecting to %s:%d\n", p->host, p->port); status = generic_connect(p, IPPROTO_TCP); if (status == UPERF_SUCCESS) set_tcp_options(p->fd, flowop_options); if (flowop_options && (strcmp(flowop_options->engine, ""))) { status = load_engine(flowop_options->engine); if (status == -1) { uperf_info( "ssl - Engine %s does NOT exist! Using the default OpenSSL softtoken", flowop_options->engine); } } if ((ssl_p->ssl = SSL_new(ctx)) == NULL) { ulog_err("Error initializng SSL"); return (-1); } sbio = BIO_new_socket(p->fd, BIO_NOCLOSE); SSL_set_bio(ssl_p->ssl, sbio, sbio); status = SSL_connect(ssl_p->ssl); if (status <= 0) { uperf_log_msg(UPERF_LOG_ERROR, 0, "ssl connect error"); return (-1); } return (0); }
static int protocol_ssl_disconnect(protocol_t * p) { int r; ssl_private_t *ssl_p = (ssl_private_t *) p->_protocol_p; if (!p) return (0); /* * workaround for the bug calling protocol_disconnect multiple * times */ if (ssl_p->ssl != NULL) { r = SSL_shutdown(ssl_p->ssl); if ((!r) && (IS_SLAVE(options))) { shutdown(p->fd, 1); r = SSL_shutdown(ssl_p->ssl); } switch (r) { case 1: case 0: case -1: break; default: uperf_log_msg(UPERF_LOG_ERROR, 0, "ssl shutdown failed"); return (-1); } if (!ssl_p->ssl) SSL_free(ssl_p->ssl); } /* workaround ends */ return (close(p->fd)); }
static void set_sctp_options(int fd, int family, flowop_options_t *f) { if (f == NULL) { return; } if (f->wndsz > 0) { generic_set_socket_buffer(fd, f->wndsz); generic_verify_socket_buffer(fd, f->wndsz); } if (FO_SCTP_NODELAY(f)) { const int on = 1; if (setsockopt(fd, IPPROTO_SCTP, SCTP_NODELAY, &on, (socklen_t)sizeof (int))) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot disable Nagle Algorithm for SCTP"); } } if ((f->sctp_in_streams > 0) || (f->sctp_out_streams > 0)) { struct sctp_initmsg init; memset(&init, 0, sizeof(struct sctp_initmsg)); init.sinit_max_instreams = f->sctp_in_streams; init.sinit_num_ostreams = f->sctp_out_streams; if (setsockopt(fd, IPPROTO_SCTP, SCTP_INITMSG, &init, (socklen_t)sizeof(struct sctp_initmsg)) < 0) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot set SCTP streams"); } } if ((f->sctp_rto_min > 0) || (f->sctp_rto_max > 0) || (f->sctp_rto_initial > 0)) { struct sctp_rtoinfo rtoinfo; memset(&rtoinfo, 0, sizeof(struct sctp_rtoinfo)); rtoinfo.srto_min = f->sctp_rto_min; rtoinfo.srto_max = f->sctp_rto_max; rtoinfo.srto_initial = f->sctp_rto_initial; if (setsockopt(fd, IPPROTO_SCTP, SCTP_RTOINFO, &rtoinfo, (socklen_t)sizeof(struct sctp_rtoinfo)) < 0) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot set SCTP RTO parameters"); } } if ((f->sctp_sack_delay > 0) || (f->sctp_sack_frequency > 0)) { #if defined(SCTP_DELAYED_SACK) struct sctp_sack_info sackinfo; memset(&sackinfo, 0, sizeof(struct sctp_sack_info)); sackinfo.sack_delay = f->sctp_sack_delay; sackinfo.sack_freq = f->sctp_sack_frequency; if (setsockopt(fd, IPPROTO_SCTP, SCTP_DELAYED_SACK, &sackinfo, (socklen_t)sizeof(struct sctp_sack_info)) < 0) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot set SCTP SACK parameters"); } #else uperf_log_msg(UPERF_LOG_WARN, ENOPROTOOPT, "Cannot set SCTP SACK parameters"); #endif } if (f->sctp_max_burst_size > 0) { struct sctp_assoc_value maxburst; memset(&maxburst, 0, sizeof(struct sctp_assoc_value)); maxburst.assoc_value = f->sctp_max_burst_size; if (setsockopt(fd, IPPROTO_SCTP, SCTP_MAX_BURST, &maxburst, (socklen_t)sizeof(struct sctp_assoc_value)) < 0) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot set max. burst parameter for SCTP"); } } if (f->sctp_max_fragment_size > 0) { struct sctp_assoc_value maxfrag; memset(&maxfrag, 0, sizeof(struct sctp_assoc_value)); maxfrag.assoc_value = f->sctp_max_fragment_size; if (setsockopt(fd, IPPROTO_SCTP, SCTP_MAXSEG, &maxfrag, (socklen_t)sizeof(struct sctp_assoc_value)) < 0) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot set max. fragment size of SCTP"); } } if ((f->sctp_hb_interval > 0) || (f->sctp_path_mtu > 0)) { struct sctp_paddrparams param; memset(¶m, 0, sizeof(struct sctp_paddrparams)); param.spp_address.ss_family = family; #if defined(UPERF_FREEBSD) || defined(UPERF_DARWIN) switch (family) { case AF_INET: param.spp_address.ss_len = sizeof(struct sockaddr_in); break; case AF_INET6: param.spp_address.ss_len = sizeof(struct sockaddr_in6); break; } #endif param.spp_hbinterval = f->sctp_hb_interval; param.spp_pathmtu = f->sctp_path_mtu; if (f->sctp_hb_interval > 0) { param.spp_flags |= SPP_HB_ENABLE; } if (f->sctp_path_mtu > 0) { param.spp_flags |= SPP_PMTUD_DISABLE; } if (setsockopt(fd, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, ¶m, (socklen_t)sizeof(struct sctp_paddrparams)) < 0) { uperf_log_msg(UPERF_LOG_WARN, errno, "Cannot set path defaults for SCTP"); } } }