diff options
author | Felix Weinrank <weinrank@fh-muenster.de> | 2019-04-02 13:52:32 +0200 |
---|---|---|
committer | Felix Weinrank <weinrank@fh-muenster.de> | 2019-04-02 13:52:32 +0200 |
commit | 19bebbee65a43e0250742b16682482199b815bcb (patch) | |
tree | edb31bf49aeba58e830b22d4be734ce4890e383a /programs | |
parent | c9080ad5265a389b24b0083683da360f0fb1f7d8 (diff) | |
download | usrsctp-19bebbee65a43e0250742b16682482199b815bcb.tar.gz |
improve http_client example to work with IPv4/IPv6 only setups
Diffstat (limited to 'programs')
-rw-r--r-- | programs/http_client.c | 129 |
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; } |