sctp_darn.c | sctp_darn.c | |||
---|---|---|---|---|
skipping to change at line 145 | skipping to change at line 145 | |||
INTER_RCV, | INTER_RCV, | |||
INTER_SNDBUF, | INTER_SNDBUF, | |||
INTER_RCVBUF, | INTER_RCVBUF, | |||
INTER_BINDX_ADD, | INTER_BINDX_ADD, | |||
INTER_BINDX_REM, | INTER_BINDX_REM, | |||
INTER_SET_PRIM, | INTER_SET_PRIM, | |||
INTER_SET_PEER_PRIM, | INTER_SET_PEER_PRIM, | |||
INTER_SHUTDOWN, | INTER_SHUTDOWN, | |||
INTER_ABORT, | INTER_ABORT, | |||
INTER_NODELAY, | INTER_NODELAY, | |||
INTER_MAXSEG | INTER_MAXSEG, | |||
INTER_HEARTBEAT, | ||||
INTER_GET_STATS | ||||
}; | }; | |||
enum shutdown_type { | enum shutdown_type { | |||
SHUTDOWN_ABORT = 0, | SHUTDOWN_ABORT = 0, | |||
SHUTDOWN_SHUTDOWN | SHUTDOWN_SHUTDOWN | |||
}; | }; | |||
struct inter_entry { | struct inter_entry { | |||
char *cmd; | char *cmd; | |||
int cmd_num; | int cmd_num; | |||
skipping to change at line 171 | skipping to change at line 173 | |||
{"sndbuf", INTER_SNDBUF}, | {"sndbuf", INTER_SNDBUF}, | |||
{"rcvbuf", INTER_RCVBUF}, | {"rcvbuf", INTER_RCVBUF}, | |||
{"bindx-add", INTER_BINDX_ADD}, | {"bindx-add", INTER_BINDX_ADD}, | |||
{"bindx-rem", INTER_BINDX_REM}, | {"bindx-rem", INTER_BINDX_REM}, | |||
{"primary", INTER_SET_PRIM}, | {"primary", INTER_SET_PRIM}, | |||
{"peer_primary", INTER_SET_PEER_PRIM}, | {"peer_primary", INTER_SET_PEER_PRIM}, | |||
{"shutdown", INTER_SHUTDOWN}, | {"shutdown", INTER_SHUTDOWN}, | |||
{"abort", INTER_ABORT}, | {"abort", INTER_ABORT}, | |||
{"nodelay", INTER_NODELAY}, | {"nodelay", INTER_NODELAY}, | |||
{"maxseg", INTER_MAXSEG}, | {"maxseg", INTER_MAXSEG}, | |||
{"heartbeat", INTER_HEARTBEAT}, | ||||
{"stats", INTER_GET_STATS}, | ||||
{NULL, -1}, | {NULL, -1}, | |||
}; | }; | |||
#define POLL_SK_MAX 256 /* The max number of sockets to select/poll. */ | #define POLL_SK_MAX 256 /* The max number of sockets to select/poll. */ | |||
int poll_sks[POLL_SK_MAX]; /* The array for using select(). */ | int poll_sks[POLL_SK_MAX]; /* The array for using select(). */ | |||
struct pollfd poll_fds[POLL_SK_MAX]; /* The array for using poll(). */ | struct pollfd poll_fds[POLL_SK_MAX]; /* The array for using poll(). */ | |||
#define POLL_SND_SIZE 16384 /* Default message size in the poll mode. */ | #define POLL_SND_SIZE 16384 /* Default message size in the poll mode. */ | |||
struct sockaddr *append_addr(const char *parm, struct sockaddr *addrs, | struct sockaddr *append_addr(const char *parm, struct sockaddr *addrs, | |||
int *ret_count) ; | int *ret_count) ; | |||
int build_endpoint(char *argv0, int portnum); | int build_endpoint(char *argv0, int portnum); | |||
static int parse_inter_commands(char *, char *, int); | static int parse_inter_commands(char *, char *, int); | |||
static void snd_func(char *); | static void snd_func(char *); | |||
static void sndbuf_func(char *, int, int, int); | static void sndbuf_func(char *, int, int, int); | |||
static void rcvbuf_func(char *, int, int, int); | static void rcvbuf_func(char *, int, int, int); | |||
static struct sockaddr *get_bindx_addr(char *, int *); | static struct sockaddr *get_bindx_addr(char *, int *); | |||
static int bindx_func(char *, int, struct sockaddr *, int, int, int); | static int bindx_func(char *, int, struct sockaddr *, int, int, int); | |||
static int connectx_func(char *, int, struct sockaddr *, int); | static int connectx_func(char *, int, struct sockaddr *, int); | |||
static void primary_func(char *, int, char *, int); | static void primary_func(char *, int, char *, int); | |||
static void peer_primary_func(char *, int, char *, int); | static void peer_primary_func(char *, int, char *, int); | |||
static void spp_hb_demand_func(char *, int, char *, int); | ||||
static int nodelay_func(char *, int, int val, int set); | static int nodelay_func(char *, int, int val, int set); | |||
static int maxseg_func(char *, int, int val, int set); | static int maxseg_func(char *, int, int val, int set); | |||
static int shutdown_func(char *argv0, int *skp, int shutdown_type); | static int shutdown_func(char *argv0, int *skp, int shutdown_type); | |||
static int get_assocstats_func(int, sctp_assoc_t); | ||||
static int test_sk_for_assoc(int sk, sctp_assoc_t assoc_id); | static int test_sk_for_assoc(int sk, sctp_assoc_t assoc_id); | |||
static char * gen_message(int); | static char * gen_message(int); | |||
static sctp_assoc_t test_recv_assoc_change(int); | static sctp_assoc_t test_recv_assoc_change(int); | |||
static sctp_assoc_t test_verify_assoc_change(struct msghdr *); | static sctp_assoc_t test_verify_assoc_change(struct msghdr *); | |||
void print_addr_buf(void * laddrs, int n_laddrs); | void print_addr_buf(void * laddrs, int n_laddrs); | |||
int print_sockaddr(struct sockaddr *sa_addr); | int print_sockaddr(struct sockaddr *sa_addr); | |||
int | int | |||
main(int argc, char *argv[]) { | main(int argc, char *argv[]) { | |||
int sk = -1; | int sk = -1; | |||
skipping to change at line 1509 | skipping to change at line 1515 | |||
printf("rcv=<int> - Do a recvmsg."); | printf("rcv=<int> - Do a recvmsg."); | |||
printf("The length is ignored for now.\n"); | printf("The length is ignored for now.\n"); | |||
printf("bindx-add=<addr> - Add a local address"); | printf("bindx-add=<addr> - Add a local address"); | |||
printf(" with bindx. \n"); | printf(" with bindx. \n"); | |||
printf("bindx-rem=<addr> - Remove a local address"); | printf("bindx-rem=<addr> - Remove a local address"); | |||
printf(" with bindx. \n"); | printf(" with bindx. \n"); | |||
printf("rcvbuf=<int> - Get/Set receive buffer size\n"); | printf("rcvbuf=<int> - Get/Set receive buffer size\n"); | |||
printf("sndbuf=<int> - Get/Set send buffer size.\n"); | printf("sndbuf=<int> - Get/Set send buffer size.\n"); | |||
printf("primary=<addr> - Get/Set association's primary\n") ; | printf("primary=<addr> - Get/Set association's primary\n") ; | |||
printf("peer_primary=addr- Set association's peer_primary\n" ); | printf("peer_primary=addr- Set association's peer_primary\n" ); | |||
printf("heartbeat=<addr> - Request a user initiated heartbea t\n"); | ||||
printf("maxseg=<int> - Get/Set Maximum fragment size.\n" ); | printf("maxseg=<int> - Get/Set Maximum fragment size.\n" ); | |||
printf("nodelay=<0|1> - Get/Set NODELAY option.\n"); | printf("nodelay=<0|1> - Get/Set NODELAY option.\n"); | |||
printf("shutdown - Shutdown the association.\n"); | printf("shutdown - Shutdown the association.\n"); | |||
printf("abort - Abort the association.\n"); | printf("abort - Abort the association.\n"); | |||
printf("stats - Print GET_ASSOC_STATS (if availab le in kernel).\n"); | ||||
printf("? - Help. Display this message.\n"); | printf("? - Help. Display this message.\n"); | |||
return -1; | return -1; | |||
} | } | |||
for (i = 0; i < REALLY_BIG; i++) { | for (i = 0; i < REALLY_BIG; i++) { | |||
if (('=' == *p) || | if (('=' == *p) || | |||
('?' == *p) || | ('?' == *p) || | |||
('\n' == *p)) { | ('\n' == *p)) { | |||
if ('=' == *p) { | if ('=' == *p) { | |||
set = 1; | set = 1; | |||
skipping to change at line 1589 | skipping to change at line 1597 | |||
bindx_func(argv0, inter_sk, tmp_addrs, len, | bindx_func(argv0, inter_sk, tmp_addrs, len, | |||
SCTP_BINDX_REM_ADDR, local_port); | SCTP_BINDX_REM_ADDR, local_port); | |||
free(tmp_addrs); | free(tmp_addrs); | |||
break; | break; | |||
case INTER_SET_PRIM: | case INTER_SET_PRIM: | |||
primary_func(argv0, inter_sk, p, set); | primary_func(argv0, inter_sk, p, set); | |||
break; | break; | |||
case INTER_SET_PEER_PRIM: | case INTER_SET_PEER_PRIM: | |||
peer_primary_func(argv0, inter_sk, p, set); | peer_primary_func(argv0, inter_sk, p, set); | |||
break; | break; | |||
case INTER_HEARTBEAT: | ||||
spp_hb_demand_func(argv0, inter_sk, p, set); | ||||
break; | ||||
case INTER_SHUTDOWN: | case INTER_SHUTDOWN: | |||
shutdown_func(argv0, &inter_sk, SHUTDOWN_SHU TDOWN); | shutdown_func(argv0, &inter_sk, SHUTDOWN_SHU TDOWN); | |||
break; | break; | |||
case INTER_ABORT: | case INTER_ABORT: | |||
shutdown_func(argv0, &inter_sk, SHUTDOWN_ABO RT); | shutdown_func(argv0, &inter_sk, SHUTDOWN_ABO RT); | |||
break; | break; | |||
case INTER_NODELAY: | case INTER_NODELAY: | |||
if (set) { | if (set) { | |||
if (*p < '0' || *p > '9') { | if (*p < '0' || *p > '9') { | |||
goto err_input; | goto err_input; | |||
skipping to change at line 1613 | skipping to change at line 1624 | |||
break; | break; | |||
case INTER_MAXSEG: | case INTER_MAXSEG: | |||
if (set) { | if (set) { | |||
if (*p < '0' || *p > '9') { | if (*p < '0' || *p > '9') { | |||
goto err_input; | goto err_input; | |||
} | } | |||
} | } | |||
val = (set) ? atoi(p) : 0; | val = (set) ? atoi(p) : 0; | |||
maxseg_func(argv0, inter_sk, val, set); | maxseg_func(argv0, inter_sk, val, set); | |||
break; | break; | |||
case INTER_GET_STATS: | ||||
get_assocstats_func(inter_sk, associd); | ||||
break; | ||||
default: | default: | |||
goto err_input; | goto err_input; | |||
break; | break; | |||
} | } | |||
return i; | return i; | |||
} | } | |||
i++; | i++; | |||
} | } | |||
skipping to change at line 1976 | skipping to change at line 1990 | |||
goto err; | goto err; | |||
return; | return; | |||
err: | err: | |||
if (!errno) | if (!errno) | |||
errno = EINVAL; | errno = EINVAL; | |||
fprintf(stderr, "%s: error %s peer_primary: %s.\n", argv0, | fprintf(stderr, "%s: error %s peer_primary: %s.\n", argv0, | |||
(set)?"setting":"getting", strerror(errno)); | (set)?"setting":"getting", strerror(errno)); | |||
} | } | |||
static void | ||||
spp_hb_demand_func(char *argv0, int sk, char *cp, int set) | ||||
{ | ||||
struct sctp_paddrparams params; | ||||
struct sockaddr_in *in_addr; | ||||
struct sockaddr_in6 *in6_addr; | ||||
int ret; | ||||
char *p = cp; | ||||
memset(¶ms, 0, sizeof(struct sctp_paddrparams)); | ||||
params.spp_assoc_id = associd; | ||||
params.spp_flags = SPP_HB_DEMAND; | ||||
if (set) { | ||||
/* Set the buffer for address parsing. */ | ||||
while ('\n' != *p) | ||||
p++; | ||||
*p = '\0'; | ||||
if (strchr(cp, '.')) { | ||||
in_addr = (struct sockaddr_in *)¶ms.spp_address; | ||||
in_addr->sin_port = htons(remote_port); | ||||
in_addr->sin_family = AF_INET; | ||||
ret = inet_pton(AF_INET, cp, &in_addr->sin_addr); | ||||
if (ret <= 0) | ||||
goto err; | ||||
} else if (strchr(cp, ':')) { | ||||
in6_addr = (struct sockaddr_in6 *)¶ms.spp_addres | ||||
s; | ||||
in6_addr->sin6_port = htons(remote_port); | ||||
in6_addr->sin6_family = AF_INET6; | ||||
ret = inet_pton(AF_INET6, cp, &in6_addr->sin6_addr); | ||||
if (ret <= 0) | ||||
goto err; | ||||
} else | ||||
goto err; | ||||
} | ||||
ret = setsockopt(sk, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, | ||||
¶ms, sizeof(struct sctp_paddrparams)); | ||||
if (ret < 0) | ||||
goto err; | ||||
return; | ||||
err: | ||||
if (!errno) | ||||
errno = EINVAL; | ||||
fprintf(stderr, "%s: error %s peer_addr_params: %s.\n", argv0, | ||||
(set)?"setting":"getting", strerror(errno)); | ||||
} | ||||
static int | static int | |||
nodelay_func(char *argv0, int sk, int val, int set) | nodelay_func(char *argv0, int sk, int val, int set) | |||
{ | { | |||
socklen_t optlen; | socklen_t optlen; | |||
int error; | int error; | |||
if (set) { | if (set) { | |||
error = setsockopt(sk, SOL_SCTP, SCTP_NODELAY, | error = setsockopt(sk, SOL_SCTP, SCTP_NODELAY, | |||
(char *)&val, sizeof(val)); | (char *)&val, sizeof(val)); | |||
} else { | } else { | |||
skipping to change at line 2160 | skipping to change at line 2224 | |||
new_connection = 1; | new_connection = 1; | |||
} else { | } else { | |||
printf("%s failed\n", sd_type); | printf("%s failed\n", sd_type); | |||
exit(1); | exit(1); | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
static int | static int | |||
get_assocstats_func(int sk, sctp_assoc_t assoc_id) | ||||
{ | ||||
int error = 0; | ||||
struct sctp_assoc_stats stats; | ||||
socklen_t len; | ||||
if (assoc_id == 0) { | ||||
printf("No association present yet\n"); | ||||
return -1; | ||||
} | ||||
memset(&stats, 0, sizeof(struct sctp_assoc_stats)); | ||||
stats.sas_assoc_id = assoc_id; | ||||
len = sizeof(struct sctp_assoc_stats); | ||||
error = getsockopt(sk, SOL_SCTP, SCTP_GET_ASSOC_STATS, | ||||
(char *)&stats, &len); | ||||
if (error != 0) { | ||||
printf("get_assoc_stats() failed %s\n", strerror(errno)); | ||||
return error; | ||||
} | ||||
printf("Retransmitted Chunks: %llu\n", stats.sas_rtxchu | ||||
nks); | ||||
printf("Gap Acknowledgements Received: %llu\n", stats.sas_gapcnt | ||||
); | ||||
printf("TSN received > next expected: %llu\n", stats.sas_outofs | ||||
eqtsns); | ||||
printf("SACKs sent: %llu\n", stats.sas_osacks | ||||
); | ||||
printf("SACKs received: %llu\n", stats.sas_isacks | ||||
); | ||||
printf("Control chunks sent : %llu\n", stats.sas_octrlc | ||||
hunks); | ||||
printf("Control chunks received : %llu\n", stats.sas_ictrlc | ||||
hunks); | ||||
printf("Ordered data chunks sent: %llu\n", stats.sas_oodchu | ||||
nks); | ||||
printf("Ordered data chunks received: %llu\n", stats.sas_iodchu | ||||
nks); | ||||
printf("Unordered data chunks sent: %llu\n", stats.sas_ouodch | ||||
unks); | ||||
printf("Unordered data chunks received: %llu\n", stats.sas_iuodch | ||||
unks); | ||||
printf("Dups received (ordered+unordered): %llu\n", stats.sas_idupch | ||||
unks); | ||||
printf("Packets sent: %llu\n", stats.sas_opacke | ||||
ts); | ||||
printf("Packets received: %llu\n", stats.sas_ipacke | ||||
ts); | ||||
printf("Maximum Observed RTO this period: %llu - Transport: ", stats | ||||
.sas_maxrto); | ||||
print_sockaddr((struct sockaddr *)&stats.sas_obs_rto_ipaddr); | ||||
printf("\n"); | ||||
return 0; | ||||
} | ||||
static int | ||||
test_sk_for_assoc(int sk, sctp_assoc_t assoc_id) | test_sk_for_assoc(int sk, sctp_assoc_t assoc_id) | |||
{ | { | |||
int error = 0; | int error = 0; | |||
struct sctp_status status; | struct sctp_status status; | |||
socklen_t status_len; | socklen_t status_len; | |||
memset(&status, 0, sizeof(status)); | memset(&status, 0, sizeof(status)); | |||
if (assoc_id) | if (assoc_id) | |||
status.sstat_assoc_id = assoc_id; | status.sstat_assoc_id = assoc_id; | |||
status_len = sizeof(struct sctp_status); | status_len = sizeof(struct sctp_status); | |||
End of changes. 10 change blocks. | ||||
1 lines changed or deleted | 124 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |