struct udp {
struct udpcommon uc;
struct udpsocks socks;
+ bool_t addr_configured;
+ unsigned counter;
};
/*
int ix=ca->ix>=0 ? ca->ix : 0;
assert(ix>=0 && ix<socks->n_socks);
- snprintf(sbuf, sizeof(sbuf), "udp:%s%s-%s",
+ snprintf(sbuf, sizeof(sbuf), "udp#%u@l%d:%s%s-%s",
+ st->counter, st->uc.cc.loc.line,
iaddr_to_string(&socks->socks[ix].addr),
ca->ix<0 && socks->n_socks>1 ? "&" : "",
iaddr_to_string(&ca->ia));
struct udpsocks *socks=&st->socks;
struct udpcommon *uc=&st->uc;
int i;
- for (i=0; i<socks->n_socks; i++)
- udp_make_socket(uc,&socks->socks[i],M_FATAL);
+ bool_t anydone=0;
+
+ for (i=0; i<socks->n_socks; i++) {
+ bool_t required=st->addr_configured
+ || (!anydone && i==socks->n_socks-1);
+ anydone += udp_make_socket(uc,&socks->socks[i],
+ required ? M_FATAL : M_WARNING);
+ }
udp_socks_register(uc,socks, uc->use_proxy ? "proxy" : "socket");
static list_t *udp_apply(closure_t *self, struct cloc loc, dict_t *context,
list_t *args)
{
+ static unsigned counter;
+
struct udp *st;
list_t *caddrl;
list_t *l;
struct udpsocks *socks=&st->socks;
struct commcommon *cc=&uc->cc;
+ st->counter=counter++;
+
union iaddr defaultaddrs[] = {
#ifdef CONFIG_IPV6
{ .sin6 = { .sin6_family=AF_INET6,
};
caddrl=dict_lookup(d,"address");
- socks->n_socks=caddrl ? list_length(caddrl) : (int)ARRAY_SIZE(defaultaddrs);
+ st->addr_configured=!!caddrl;
+ socks->n_socks=st->addr_configured ? list_length(caddrl)
+ : (int)ARRAY_SIZE(defaultaddrs);
if (socks->n_socks<=0 || socks->n_socks>UDP_MAX_SOCKETS)
cfgfatal(cc->loc,"udp","`address' must be 1..%d addresses",
UDP_MAX_SOCKETS);
for (i=0; i<socks->n_socks; i++) {
struct udpsock *us=&socks->socks[i];
- if (!list_length(caddrl)) {
+ if (!st->addr_configured) {
us->addr=defaultaddrs[i];
} else {
string_item_to_iaddr(list_elem(caddrl,i),uc->port,&us->addr,"udp");