This may be useful for testing and on some networks where both address
families are available but only one works or is desired. The last option
specified takes precedence. If neither option is specified, the usual
behaviour (AF_UNSPEC) remains.
---
catgirl.1 | 6 +++++-
chat.c | 9 +++++++--
chat.h | 2 +-
irc.c | 4 ++--
4 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/catgirl.1 b/catgirl.1
index 16a59da..efe148f 100644
--- a/catgirl.1
+++ b/catgirl.1
@@ -8,7 +8,7 @@
.
.Sh SYNOPSIS
.Nm
-.Op Fl KRelqv
+.Op Fl 46KRelqv
.Op Fl C Ar copy
.Op Fl H Ar hash
.Op Fl I Ar highlight
@@ -92,6 +92,10 @@ The options are listed below
following their corresponding flags.
.
.Bl -tag -width Ds
+.It Fl 4 | Cm ipv4
+Use IPv4 only.
+.It Fl 6 | Cm ipv6
+Use IPv6 only.
.It Fl C Ar util | Cm copy No = Ar util
Set the utility used by
.Ic /copy .
diff --git a/chat.c b/chat.c
index b74fdc0..fb7c916 100644
--- a/chat.c
+++ b/chat.c
@@ -227,6 +227,7 @@ int main(int argc, char *argv[]) {
bool insecure = false;
bool printCert = false;
+ int ai_family = 0;
const char *bind = NULL;
const char *host = NULL;
const char *port = "6697";
@@ -243,6 +244,8 @@ int main(int argc, char *argv[]) {
struct option options[] = {
{ .val = '!', .name = "insecure", no_argument },
+ { .val = '4', .name = "ipv4", no_argument },
+ { .val = '6', .name = "ipv6", no_argument },
{ .val = 'C', .name = "copy", required_argument },
{ .val = 'H', .name = "hash", required_argument },
{ .val = 'I', .name = "highlight", required_argument },
@@ -284,6 +287,8 @@ int main(int argc, char *argv[]) {
for (int opt; 0 < (opt = getopt_config(argc, argv, opts, options, NULL));) {
switch (opt) {
break; case '!': insecure = true;
+ break; case '4': ai_family = 4;
+ break; case '6': ai_family = 6;
break; case 'C': utilPush(&urlCopyUtil, optarg);
break; case 'H': parseHash(optarg);
break; case 'I': filterAdd(Hot, optarg);
@@ -327,7 +332,7 @@ int main(int argc, char *argv[]) {
if (error) err(EX_OSERR, "pledge");
#endif
ircConfig(true, NULL, NULL, NULL);
- ircConnect(bind, host, port);
+ ircConnect(bind, host, port, ai_family);
ircPrintCert();
ircClose();
return EX_OK;
@@ -392,7 +397,7 @@ int main(int argc, char *argv[]) {
uiDraw();
sandboxEarly(log);
- int irc = ircConnect(bind, host, port);
+ int irc = ircConnect(bind, host, port, ai_family);
sandboxLate(irc);
ircHandshake();
diff --git a/chat.h b/chat.h
index 1c46f00..24a0b3f 100644
--- a/chat.h
+++ b/chat.h
@@ -237,7 +237,7 @@ struct Message {
void ircConfig(
bool insecure, const char *trust, const char *cert, const char *priv
);
-int ircConnect(const char *bind, const char *host, const char *port);
+int ircConnect(const char *bind, const char *host, const char *port, int ai_family);
void ircHandshake(void);
void ircPrintCert(void);
void ircRecv(void);
diff --git a/irc.c b/irc.c
index 20e9f91..fcf437d 100644
--- a/irc.c
+++ b/irc.c
@@ -106,14 +106,14 @@ void ircConfig(
if (error) errx(EX_SOFTWARE, "tls_configure: %s", tls_error(client));
}
-int ircConnect(const char *bindHost, const char *host, const char *port) {
+int ircConnect(const char *bindHost, const char *host, const char *port, int ai_family) {
assert(client);
int error;
int sock = -1;
struct addrinfo *head;
struct addrinfo hints = {
- .ai_family = AF_UNSPEC,
+ .ai_family = ai_family == 4 ? AF_INET : ai_family == 6 ? AF_INET6 : AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
.ai_protocol = IPPROTO_TCP,
};
--
2.35.1