File fIcy-use_getaddrinfo.patch of Package fIcy
From 759ccef40fb82b5dc7b1f0800208557cc2024aea Mon Sep 17 00:00:00 2001
From: Yuri D'Elia <wavexx@thregr.org>
Date: Sat, 3 Feb 2018 15:07:16 +0100
Subject: [PATCH] Use getaddrinfo to resolve hostnames
- Use getaddrinfo also to resolve service names
- Get rid of getSrvName as a result
- Accept service names everywhere
- Print correct port name/service on connect
---
Makefile | 12 ++++++------
htfollow.cc | 11 +++++++----
http.cc | 18 ++++--------------
http.hh | 8 +++-----
resolver.cc | 37 -------------------------------------
resolver.hh | 22 ----------------------
socket.cc | 41 ++++++++++++++++++++++++-----------------
socket.hh | 12 ++++++------
urlparse.cc | 6 +++---
urlparse.hh | 8 ++++----
10 files changed, 57 insertions(+), 118 deletions(-)
delete mode 100644 resolver.cc
delete mode 100644 resolver.hh
diff --git a/Makefile b/Makefile
index 786d05e..e3a50f7 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
# Copyright(c) 2004-2017 by wave++ (Yuri D'Elia) <wavexx@thregr.org>
# Flags
-CWARN += -Wall -Wextra -Wno-unused-parameter
+CWARN += -Wall -Wextra -Wno-unused-parameter -Wno-shadow
CXXFLAGS += -std=c++03 $(CWARN)
CPPFLAGS += -MD -D_FILE_OFFSET_BITS=64
@@ -12,12 +12,12 @@ PREFIX := /usr/local
# Objects/targets
TARGETS := fIcy fResync fPls
-fIcy_OBJECTS := msg.o resolver.o socket.o http.o tmparse.o urlencode.o \
- base64.o urlparse.o hdrparse.o sanitize.o htfollow.o authparse.o \
- match.o icy.o rewrite.o fIcy.o
+fIcy_OBJECTS := msg.o socket.o http.o tmparse.o urlencode.o base64.o \
+ urlparse.o hdrparse.o sanitize.o htfollow.o authparse.o match.o \
+ icy.o rewrite.o fIcy.o
fResync_OBJECTS := msg.o mpeg.o copy.o fResync.o
-fPls_OBJECTS := msg.o resolver.o socket.o http.o tmparse.o urlencode.o \
- base64.o urlparse.o hdrparse.o sanitize.o htfollow.o authparse.o \
+fPls_OBJECTS := msg.o socket.o http.o tmparse.o urlencode.o base64.o \
+ urlparse.o hdrparse.o sanitize.o htfollow.o authparse.o \
plsparse.o fPls.o
diff --git a/htfollow.cc b/htfollow.cc
index c65ec5f..4b18f3b 100644
--- a/htfollow.cc
+++ b/htfollow.cc
@@ -51,11 +51,14 @@ htFollow(map<string, string>& pReply, const URL& url, const Http::Header qHeader
auto_ptr<Socket> s;
for(size_t level = limit, retry = retries;;)
{
- msg("connecting to (%s %d)", sanitize_esc(buf.server).c_str(), buf.port);
- Http::Http httpc(sanitize_esc(buf.server).c_str(),
- buf.port, (timeout? &tmBuf: NULL));
+ // display the correct port name/number
+ if(!buf.port.size())
+ buf.port = Http::Proto::port;
- msg("requesting data on (%s)", sanitize_esc(buf.path).c_str());
+ msg("connecting to %s:%s", sanitize_esc(buf.server).c_str(), buf.port.c_str());
+ Http::Http httpc(buf.server.c_str(), buf.port.c_str(), (timeout? &tmBuf: NULL));
+
+ msg("requesting data on %s", sanitize_esc(buf.path).c_str());
Http::Header aHeaders;
Http::Reply reply(&aHeaders);
try
diff --git a/http.cc b/http.cc
index 5603f60..00474ac 100644
--- a/http.cc
+++ b/http.cc
@@ -33,6 +33,7 @@ namespace Http
{
// definitions
const char* proto = "http";
+ const char* port = "80";
const char* protoTy = "tcp";
const char* version = "HTTP/1.0";
const char* endl = "\r\n";
@@ -51,10 +52,10 @@ namespace Http
}
- Http::Http(const char* host, const int port, const timeval* timeout)
+ Http::Http(const char* host, const char* port, const timeval* timeout)
{
this->host = strdup(host);
- this->port = (port? port: getSrvPort());
+ this->port = strdup(port? port: Proto::port);
if(!timeout)
this->timeout = NULL;
@@ -69,23 +70,12 @@ namespace Http
Http::~Http()
{
delete []host;
+ delete []port;
if(timeout)
delete timeout;
}
- int
- Http::getSrvPort()
- {
- servent* se(getservbyname(Proto::proto, Proto::protoTy));
- if(!se)
- throw
- std::runtime_error("error while trying to identify http port number");
-
- return ntohs(se->s_port);
- }
-
-
void
Http::readReply(Socket& s, Reply& reply)
{
diff --git a/http.hh b/http.hh
index 0b75cf0..1e94cdd 100644
--- a/http.hh
+++ b/http.hh
@@ -22,6 +22,7 @@ namespace Http
{
// parameters
const extern char* proto;
+ const extern char* port;
const extern char* protoTy;
const extern char* version;
const size_t hdrLen = 1024;
@@ -77,13 +78,10 @@ namespace Http
class Http
{
char* host;
- int port;
+ char* port;
timeval* timeout;
// http functions
- int
- getSrvPort();
-
void
readReply(Socket& s, Reply& reply);
@@ -97,7 +95,7 @@ namespace Http
public:
// de/constructors
- Http(const char* host, const int port = 0, const timeval* timeout = NULL);
+ Http(const char* host, const char* port = NULL, const timeval* timeout = NULL);
~Http();
// basic functionality
diff --git a/resolver.cc b/resolver.cc
deleted file mode 100644
index 5e8aa24..0000000
--- a/resolver.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * resolver - IN4/6 address resolver - implementation
- * Copyright(c) 2003-2008 of wave++ (Yuri D'Elia)
- * Distributed under GNU LGPL without ANY warranty.
- */
-
-// local headers
-#include "resolver.hh"
-
-// system headers
-#include <stdexcept>
-
-// c system headers
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <string.h>
-
-
-// implementation
-in_addr_t
-resolve(const char* host, in_addr_t* addr)
-{
- // call the native gethostbyname
- hostent* he(gethostbyname(host));
- if(!he)
- throw std::runtime_error(hstrerror(h_errno));
-
- in_addr_t r;
- memcpy(&r, *he->h_addr_list, sizeof(r));
- if(addr)
- *addr = r;
-
- return r;
-}
-
diff --git a/resolver.hh b/resolver.hh
deleted file mode 100644
index df6e265..0000000
--- a/resolver.hh
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * resolver - IN4/6 address resolver
- * Copyright(c) 2003-2008 of wave++ (Yuri D'Elia)
- * Distributed under GNU LGPL without ANY warranty.
- */
-
-#ifndef resolver_hh
-#define resolver_hh
-
-// system headers
-#include <cstddef>
-
-// c system headers
-#include <arpa/inet.h>
-
-
-// resolve use gethostbyname internally, which is not reentrant
-in_addr_t
-resolve(const char* host, in_addr_t* addr = NULL);
-
-#endif
-
diff --git a/socket.cc b/socket.cc
index f58eaa2..db2bd40 100644
--- a/socket.cc
+++ b/socket.cc
@@ -6,13 +6,11 @@
// local headers
#include "socket.hh"
-#include "resolver.hh"
// system headers
#include <stdexcept>
// c system headers
-#include <netinet/in.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
@@ -31,26 +29,16 @@ Socket::~Socket() throw()
void
-Socket::open(const in_addr_t& host, const int port, const timeval* timeout)
+Socket::open(const addrinfo& ai, const timeval* timeout)
{
if(conn)
close();
- fd = socket(AF_INET, SOCK_STREAM, 0);
+ fd = socket(ai.ai_family, ai.ai_socktype, ai.ai_protocol);
if(fd == -1)
throw std::runtime_error(strerror(errno));
- // bind the socket
- sockaddr_in addr;
- addr.sin_family = AF_INET;
-
- // fetch the port number
- addr.sin_port = htons(port);
- addr.sin_addr.s_addr = host;
- memset(&(addr.sin_zero), 0, sizeof(addr.sin_zero));
-
- if(::connect(fd, reinterpret_cast<struct sockaddr*>(&addr),
- sizeof(struct sockaddr)) == -1)
+ if(::connect(fd, ai.ai_addr, ai.ai_addrlen) == -1)
throw std::runtime_error(strerror(errno));
if(!timeout)
@@ -66,9 +54,28 @@ Socket::open(const in_addr_t& host, const int port, const timeval* timeout)
void
-Socket::open(const char* host, const int port, const timeval* timeout)
+Socket::open(const char* host, const char* port, const timeval* timeout)
{
- open(resolve(host), port, timeout);
+ // resolve the hostname
+ addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ addrinfo* ai;
+ int r = getaddrinfo(host, port, &hints, &ai);
+ if(r)
+ throw std::runtime_error(gai_strerror(r));
+
+ // connect
+ try { open(*ai, timeout); }
+ catch(...)
+ {
+ freeaddrinfo(ai);
+ throw;
+ }
+
+ freeaddrinfo(ai);
}
diff --git a/socket.hh b/socket.hh
index 33a4003..d810de3 100644
--- a/socket.hh
+++ b/socket.hh
@@ -11,8 +11,8 @@
#include <cstddef>
// c system headers
-#include <arpa/inet.h>
#include <sys/socket.h>
+#include <netdb.h>
#include <sys/time.h>
// not all systems define sock_t
@@ -31,13 +31,13 @@ protected:
sock_t fd;
public:
- Socket(const in_addr_t& host, const int port, const timeval* timeout = NULL)
+ Socket(const addrinfo& ai, const timeval* timeout = NULL)
: conn(false)
{
- open(host, port, timeout);
+ open(ai, timeout);
}
- Socket(const char* host, const int port, const timeval* timeout = NULL)
+ Socket(const char* host, const char* port, const timeval* timeout = NULL)
: conn(false)
{
open(host, port, timeout);
@@ -50,10 +50,10 @@ public:
~Socket() throw();
void
- open(const char* host, const int port, const timeval* timeout = NULL);
+ open(const char* host, const char* port, const timeval* timeout = NULL);
void
- open(const in_addr_t& host, const int port, const timeval* timeout = NULL);
+ open(const addrinfo& ai, const timeval* timeout = NULL);
void
close(const int how = 0);
diff --git a/urlparse.cc b/urlparse.cc
index 3fd04b6..d28c593 100644
--- a/urlparse.cc
+++ b/urlparse.cc
@@ -16,7 +16,7 @@ using std::string;
// implementation
void
-urlParse(string& proto, string& server, int& port, string& path,
+urlParse(string& proto, string& server, string& port, string& path,
const string& url)
{
// check for proto
@@ -44,10 +44,10 @@ urlParse(string& proto, string& server, int& port, string& path,
if(colon == string::npos || colon > slash)
{
colon = slash;
- port = 0;
+ port.clear();
}
else
- port = atoi(url.substr(colon + 1, slash).c_str());
+ port = url.substr(colon + 1, slash - colon - 1);
// finally, the server
server = url.substr(protoEnd,
diff --git a/urlparse.hh b/urlparse.hh
index 9c171dc..09d3a1b 100644
--- a/urlparse.hh
+++ b/urlparse.hh
@@ -13,8 +13,8 @@
// underlying parsers
void
-urlParse(std::string& proto, std::string& server, int& port, std::string& path,
- const std::string& url);
+urlParse(std::string& proto, std::string& server, std::string& port,
+ std::string& path, const std::string& url);
// common structures
@@ -25,7 +25,7 @@ struct URL
{}
URL(const std::string& proto, const std::string& server,
- const int port, const std::string& path)
+ const std::string& port, const std::string& path)
: proto(proto), server(server), port(port), path(path)
{}
@@ -47,7 +47,7 @@ struct URL
// data
std::string proto;
std::string server;
- int port;
+ std::string port;
std::string path;
};