UDP: rearrange udp_connect/udp_sendinit

This commit is contained in:
Jaroslav Kysela 2015-03-03 16:01:01 +01:00
parent cbf1b15d00
commit cfbe927b43
2 changed files with 58 additions and 29 deletions

View file

@ -39,23 +39,27 @@
extern int tcp_preferred_address_family;
static int
udp_resolve( udp_connection_t *uc, int receiver )
udp_resolve( udp_connection_t *uc,
struct sockaddr_storage *ss,
const char *host,
int port, int *multicast,
int receiver )
{
struct addrinfo hints, *res, *ressave, *use = NULL;
char port_buf[6];
int x;
snprintf(port_buf, 6, "%d", uc->port);
snprintf(port_buf, 6, "%d", port);
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_flags = (receiver ? AI_PASSIVE : 0) | AI_NUMERICSERV;
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
x = getaddrinfo(uc->host, port_buf, &hints, &res);
x = getaddrinfo(host, port_buf, &hints, &res);
if (x < 0) {
tvhlog(LOG_ERR, uc->subsystem, "getaddrinfo: %s: %s",
uc->host != NULL ? uc->host : "*",
host != NULL ? host : "*",
x == EAI_SYSTEM ? strerror(errno) : gai_strerror(x));
return -1;
}
@ -71,19 +75,19 @@ udp_resolve( udp_connection_t *uc, int receiver )
res = res->ai_next;
}
if (use->ai_family == AF_INET6) {
uc->ip.ss_family = AF_INET6;
IP_AS_V6(uc->ip, port) = htons(uc->port);
memcpy(&IP_AS_V6(uc->ip, addr), &((struct sockaddr_in6 *)use->ai_addr)->sin6_addr,
ss->ss_family = AF_INET6;
IP_AS_V6(*ss, port) = htons(port);
memcpy(&IP_AS_V6(*ss, addr), &((struct sockaddr_in6 *)use->ai_addr)->sin6_addr,
sizeof(struct in6_addr));
uc->multicast = !!IN6_IS_ADDR_MULTICAST(&IP_AS_V6(uc->ip, addr));
*multicast = !!IN6_IS_ADDR_MULTICAST(&IP_AS_V6(*ss, addr));
} else if (use->ai_family == AF_INET) {
uc->ip.ss_family = AF_INET;
IP_AS_V4(uc->ip, port) = htons(uc->port);
IP_AS_V4(uc->ip, addr) = ((struct sockaddr_in *)use->ai_addr)->sin_addr;
uc->multicast = !!IN_MULTICAST(ntohl(IP_AS_V4(uc->ip, addr.s_addr)));
ss->ss_family = AF_INET;
IP_AS_V4(*ss, port) = htons(port);
IP_AS_V4(*ss, addr) = ((struct sockaddr_in *)use->ai_addr)->sin_addr;
*multicast = !!IN_MULTICAST(ntohl(IP_AS_V4(*ss, addr.s_addr)));
}
freeaddrinfo(ressave);
if (uc->ip.ss_family != AF_INET && uc->ip.ss_family != AF_INET6) {
if (ss->ss_family != AF_INET && ss->ss_family != AF_INET6) {
tvherror(uc->subsystem, "%s - failed to process host '%s'", uc->name, uc->host);
return -1;
}
@ -167,7 +171,7 @@ udp_bind ( const char *subsystem, const char *name,
uc->name = name ? strdup(name) : NULL;
uc->rxtxsize = rxsize;
if (udp_resolve(uc, 1) < 0) {
if (udp_resolve(uc, &uc->ip, uc->host, port, &uc->multicast, 1)) {
udp_close(uc);
return UDP_FATAL_ERROR;
}
@ -206,7 +210,7 @@ udp_bind ( const char *subsystem, const char *name,
memset(&m, 0, sizeof(m));
/* Bind */
if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in)) == -1) {
if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in))) {
inet_ntop(AF_INET, &IP_AS_V4(uc->ip, addr), buf, sizeof(buf));
tvherror(subsystem, "%s - cannot bind %s:%hu [e=%s]",
name, buf, ntohs(IP_AS_V4(uc->ip, port)), strerror(errno));
@ -240,7 +244,7 @@ udp_bind ( const char *subsystem, const char *name,
memset(&m, 0, sizeof(m));
/* Bind */
if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in6)) == -1) {
if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in6))) {
inet_ntop(AF_INET6, &IP_AS_V6(uc->ip, addr), buf, sizeof(buf));
tvherror(subsystem, "%s - cannot bind %s:%hu [e=%s]",
name, buf, ntohs(IP_AS_V6(uc->ip, port)), strerror(errno));
@ -335,27 +339,19 @@ fail:
}
udp_connection_t *
udp_connect ( const char *subsystem, const char *name,
const char *host, int port,
const char *ifname, int txsize )
udp_sendinit ( const char *subsystem, const char *name,
const char *ifname, int txsize )
{
int fd, ifindex;
udp_connection_t *uc;
uc = calloc(1, sizeof(udp_connection_t));
uc->fd = -1;
uc->host = host ? strdup(host) : NULL;
uc->port = port;
uc->ifname = ifname ? strdup(ifname) : NULL;
uc->subsystem = subsystem ? strdup(subsystem) : NULL;
uc->name = name ? strdup(name) : NULL;
uc->rxtxsize = txsize;
if (udp_resolve(uc, 1) < 0) {
udp_close(uc);
return UDP_FATAL_ERROR;
}
/* Open socket */
if ((fd = tvh_socket(uc->ip.ss_family, SOCK_DGRAM, 0)) == -1) {
tvherror(subsystem, "%s - failed to create socket [%s]",
@ -418,6 +414,33 @@ error:
return NULL;
}
int
udp_connect( udp_connection_t *uc, const char *name,
const char *host, int port )
{
char buf[50];
int r;
if (uc == NULL || uc == UDP_FATAL_ERROR)
return -1;
uc->peer_host = host ? strdup(host) : NULL;
uc->peer_port = port;
uc->peer_multicast = 0;
if (udp_resolve(uc, &uc->peer, host, port, &uc->peer_multicast, 1))
return -1;
if (connect(uc->fd, (struct sockaddr *)&uc->peer, sizeof(struct sockaddr_in))) {
inet_ntop(uc->peer.ss_family, IP_IN_ADDR(uc->peer), buf, sizeof(buf));
tvherror(uc->subsystem, "%s - cannot bind %s:%hu [e=%s]",
name, buf, ntohs(IP_PORT(uc->peer)), strerror(errno));
r = -errno;
return r;
}
return 0;
}
void
udp_close( udp_connection_t *uc )
{

View file

@ -31,6 +31,10 @@ typedef struct udp_connection {
int multicast;
char *ifname;
struct sockaddr_storage ip;
char *peer_host;
int peer_port;
int peer_multicast;
struct sockaddr_storage peer;
int fd;
char *subsystem;
char *name;
@ -48,9 +52,11 @@ udp_bind_double ( udp_connection_t **_u1, udp_connection_t **_u2,
const char *ifname, int rxsize1, int rxsize2,
int txsize1, int txsize2 );
udp_connection_t *
udp_connect ( const char *subsystem, const char *name,
const char *host, int port,
const char *ifname, int txsize );
udp_sendinit ( const char *subsystem, const char *name,
const char *ifname, int txsize );
int
udp_connect ( udp_connection_t *uc, const char *name,
const char *host, int port );
void
udp_close ( udp_connection_t *uc );
int