aboutsummaryrefslogtreecommitdiff
path: root/programs
diff options
context:
space:
mode:
authorFelix Weinrank <weinrank@fh-muenster.de>2019-04-02 13:52:32 +0200
committerFelix Weinrank <weinrank@fh-muenster.de>2019-04-02 13:52:32 +0200
commit19bebbee65a43e0250742b16682482199b815bcb (patch)
treeedb31bf49aeba58e830b22d4be734ce4890e383a /programs
parentc9080ad5265a389b24b0083683da360f0fb1f7d8 (diff)
downloadusrsctp-19bebbee65a43e0250742b16682482199b815bcb.tar.gz
improve http_client example to work with IPv4/IPv6 only setups
Diffstat (limited to 'programs')
-rw-r--r--programs/http_client.c129
1 files changed, 81 insertions, 48 deletions
diff --git a/programs/http_client.c b/programs/http_client.c
index 23a3c793..014beae1 100644
--- a/programs/http_client.c
+++ b/programs/http_client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Felix Weinrank
+ * Copyright (C) 2016-2019 Felix Weinrank
*
* All rights reserved.
*
@@ -99,20 +99,53 @@ int
main(int argc, char *argv[])
{
struct socket *sock;
+ struct sockaddr *addr;
+ socklen_t addr_len;
struct sockaddr_in addr4;
struct sockaddr_in6 addr6;
+ struct sockaddr_in bind4;
+ struct sockaddr_in6 bind6;
struct sctp_udpencaps encaps;
struct sctp_sndinfo sndinfo;
struct sctp_rtoinfo rtoinfo;
struct sctp_initmsg initmsg;
- int result;
+ int result = 0;
+ uint8_t address_family = 0;
if (argc < 3) {
printf("Usage: http_client remote_addr remote_port [local_port] [local_encaps_port] [remote_encaps_port] [uri]\n");
return(EXIT_FAILURE);
}
- result = 0;
+ memset((void *)&addr4, 0, sizeof(struct sockaddr_in));
+ memset((void *)&addr6, 0, sizeof(struct sockaddr_in6));
+
+ if (inet_pton(AF_INET, argv[1], &addr4.sin_addr) == 1) {
+ address_family = AF_INET;
+
+ addr = (struct sockaddr *)&addr4;
+ addr_len = sizeof(addr4);
+#ifdef HAVE_SIN_LEN
+ addr4.sin_len = sizeof(struct sockaddr_in);
+#endif
+ addr4.sin_family = AF_INET;
+ addr4.sin_port = htons(atoi(argv[2]));
+ } else if (inet_pton(AF_INET6, argv[1], &addr6.sin6_addr) == 1) {
+ address_family = AF_INET6;
+
+ addr = (struct sockaddr *)&addr6;
+ addr_len = sizeof(addr6);
+#ifdef HAVE_SIN6_LEN
+ addr6.sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ addr6.sin6_family = AF_INET6;
+ addr6.sin6_port = htons(atoi(argv[2]));
+ } else {
+ printf("Unsupported destination address - use IPv4 or IPv6 address\n");
+ result = 1;
+ goto out;
+ }
+
if (argc > 4) {
usrsctp_init(atoi(argv[4]), NULL, debug_printf);
} else {
@@ -125,9 +158,9 @@ main(int argc, char *argv[])
usrsctp_sysctl_set_sctp_blackhole(2);
- if ((sock = usrsctp_socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, NULL)) == NULL) {
+ if ((sock = usrsctp_socket(address_family, SOCK_STREAM, IPPROTO_SCTP, receive_cb, NULL, 0, NULL)) == NULL) {
perror("usrsctp_socket");
- result = 1;
+ result = 2;
goto out;
}
@@ -148,34 +181,52 @@ main(int argc, char *argv[])
if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_INITMSG, (const void *)&initmsg, (socklen_t)sizeof(struct sctp_initmsg)) < 0) {
perror("setsockopt");
usrsctp_close(sock);
- result = 3;
+ result = 4;
goto out;
}
if (argc > 3) {
- memset((void *)&addr6, 0, sizeof(struct sockaddr_in6));
+
+ if (address_family == AF_INET) {
+ memset((void *)&bind4, 0, sizeof(struct sockaddr_in));
#ifdef HAVE_SIN6_LEN
- addr6.sin6_len = sizeof(struct sockaddr_in6);
+ bind4.sin_len = sizeof(struct sockaddr_in6);
#endif
- addr6.sin6_family = AF_INET6;
- addr6.sin6_port = htons(atoi(argv[3]));
- addr6.sin6_addr = in6addr_any;
- if (usrsctp_bind(sock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0) {
- perror("bind");
- usrsctp_close(sock);
- result = 2;
- goto out;
+ bind4.sin_family = AF_INET;
+ bind4.sin_port = htons(atoi(argv[3]));
+ bind4.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ if (usrsctp_bind(sock, (struct sockaddr *)&bind4, sizeof(bind4)) < 0) {
+ perror("bind");
+ usrsctp_close(sock);
+ result = 5;
+ goto out;
+ }
+ } else {
+ memset((void *)&bind6, 0, sizeof(struct sockaddr_in6));
+#ifdef HAVE_SIN6_LEN
+ bind6.sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ bind6.sin6_family = AF_INET6;
+ bind6.sin6_port = htons(atoi(argv[3]));
+ bind6.sin6_addr = in6addr_any;
+ if (usrsctp_bind(sock, (struct sockaddr *)&bind6, sizeof(bind6)) < 0) {
+ perror("bind");
+ usrsctp_close(sock);
+ result = 6;
+ goto out;
+ }
}
}
if (argc > 5) {
memset(&encaps, 0, sizeof(struct sctp_udpencaps));
- encaps.sue_address.ss_family = AF_INET6;
+ encaps.sue_address.ss_family = address_family;
encaps.sue_port = htons(atoi(argv[5]));
if (usrsctp_setsockopt(sock, IPPROTO_SCTP, SCTP_REMOTE_UDP_ENCAPS_PORT, (const void *)&encaps, (socklen_t)sizeof(struct sctp_udpencaps)) < 0) {
perror("setsockopt");
usrsctp_close(sock);
- result = 3;
+ result = 7;
goto out;
}
}
@@ -197,46 +248,28 @@ main(int argc, char *argv[])
printf("\nHTTP request:\n%s\n", request);
printf("\nHTTP response:\n");
- memset((void *)&addr4, 0, sizeof(struct sockaddr_in));
- memset((void *)&addr6, 0, sizeof(struct sockaddr_in6));
-#ifdef HAVE_SIN_LEN
- addr4.sin_len = sizeof(struct sockaddr_in);
-#endif
-#ifdef HAVE_SIN6_LEN
- addr6.sin6_len = sizeof(struct sockaddr_in6);
-#endif
- addr4.sin_family = AF_INET;
- addr6.sin6_family = AF_INET6;
- addr4.sin_port = htons(atoi(argv[2]));
- addr6.sin6_port = htons(atoi(argv[2]));
- if (inet_pton(AF_INET6, argv[1], &addr6.sin6_addr) == 1) {
- if (usrsctp_connect(sock, (struct sockaddr *)&addr6, sizeof(struct sockaddr_in6)) < 0) {
- perror("usrsctp_connect");
- usrsctp_close(sock);
- result = 4;
- goto out;
- }
- } else if (inet_pton(AF_INET, argv[1], &addr4.sin_addr) == 1) {
- if (usrsctp_connect(sock, (struct sockaddr *)&addr4, sizeof(struct sockaddr_in)) < 0) {
- perror("usrsctp_connect");
- usrsctp_close(sock);
- result = 5;
- goto out;
- }
- } else {
- printf("Illegal destination address\n");
+ if (usrsctp_connect(sock, addr, addr_len) < 0) {
+ perror("usrsctp_connect");
usrsctp_close(sock);
- result = 6;
+
+ if (errno == ECONNREFUSED) {
+ result = 8;
+ } else {
+ result = 9;
+ }
+
goto out;
}
+ // WAS HERE!!!
+
memset(&sndinfo, 0, sizeof(struct sctp_sndinfo));
sndinfo.snd_ppid = htonl(63); /* PPID for HTTP/SCTP */
/* send GET request */
if (usrsctp_sendv(sock, request, strlen(request), NULL, 0, &sndinfo, sizeof(struct sctp_sndinfo), SCTP_SENDV_SNDINFO, 0) < 0) {
perror("usrsctp_sendv");
usrsctp_close(sock);
- result = 6;
+ result = 11;
goto out;
}