+
+#if defined(IPV6_TCLASS) && defined(IPTOS_LOWDELAY)
+ option = IPTOS_LOWDELAY;
+ setsockopt(c->socket, IPPROTO_IPV6, IPV6_TCLASS, (void *)&option, sizeof(option));
+#endif
+}
+
+static bool bind_to_interface(int sd) {
+ char *iface;
+
+#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
+ struct ifreq ifr;
+ int status;
+#endif /* defined(SOL_SOCKET) && defined(SO_BINDTODEVICE) */
+
+ if(!get_config_string(lookup_config(config_tree, "BindToInterface"), &iface)) {
+ return true;
+ }
+
+#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_ifrn.ifrn_name, iface, IFNAMSIZ);
+ ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
+
+ status = setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
+
+ if(status) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Can't bind to interface %s: %s", iface,
+ sockstrerror(sockerrno));
+ return false;
+ }
+
+#else /* if !defined(SOL_SOCKET) || !defined(SO_BINDTODEVICE) */
+ logger(DEBUG_ALWAYS, LOG_WARNING, "%s not supported on this platform", "BindToInterface");
+#endif
+
+ return true;
+}
+
+static bool bind_to_address(connection_t *c) {
+ int s = -1;
+
+ for(int i = 0; i < listen_sockets && listen_socket[i].bindto; i++) {
+ if(listen_socket[i].sa.sa.sa_family != c->address.sa.sa_family) {
+ continue;
+ }
+
+ if(s >= 0) {
+ return false;
+ }
+
+ s = i;
+ }
+
+ if(s < 0) {
+ return false;
+ }
+
+ sockaddr_t sa = listen_socket[s].sa;
+
+ if(sa.sa.sa_family == AF_INET) {
+ sa.in.sin_port = 0;
+ } else if(sa.sa.sa_family == AF_INET6) {
+ sa.in6.sin6_port = 0;
+ }
+
+ if(bind(c->socket, &sa.sa, SALEN(sa.sa))) {
+ logger(DEBUG_CONNECTIONS, LOG_WARNING, "Can't bind outgoing socket: %s", sockstrerror(sockerrno));
+ return false;
+ }
+
+ return true;