+ struct udpcommon *uc=&st->uc;
+ struct udpsocks *socks=&st->socks;
+ uint8_t *sa;
+
+ if (uc->use_proxy) {
+ struct udpsock *us=&socks->socks[0];
+ sa=buf_prepend(buf,8);
+ if (dest->ia.sa.sa_family != AF_INET) {
+ Message(M_INFO,
+ "udp: proxy means dropping outgoing non-IPv4 packet to %s\n",
+ iaddr_to_string(&dest->ia));
+ return False;
+ }
+ memcpy(sa,&dest->ia.sin.sin_addr,4);
+ memset(sa+4,0,4);
+ memcpy(sa+6,&dest->ia.sin.sin_port,2);
+ int r=sendto(us->fd,sa,buf->size+8,0,&uc->proxy.sa,
+ iaddr_socklen(&uc->proxy));
+ udp_sock_experienced(0,uc, "proxy",us, 1,0, r,errno);
+ buf_unprepend(buf,8);
+ } else {
+ int i,r;
+ bool_t allunsupported=True;
+ int af=dest->ia.sa.sa_family;
+ for (i=0; i<socks->n_socks; i++) {
+ struct udpsock *us=&socks->socks[i];
+ if (us->addr.sa.sa_family != af)
+ /* no point even trying */
+ continue;
+ r=sendto(us->fd, buf->start, buf->size, 0,
+ &dest->ia.sa, iaddr_socklen(&dest->ia));
+ udp_sock_experienced(0,uc, "socket",us, 1,af, r,errno);
+ if (r>=0) return True;
+ if (!(errno==EAFNOSUPPORT || errno==ENETUNREACH))
+ /* who knows what that error means? */
+ allunsupported=False;
+ }
+ return !allunsupported; /* see doc for comm_sendmsg_fn in secnet.h */
+ }
+
+ return True;