+ int nfd;
+ char *addrstr;
+ int option;
+
+ cp();
+
+ nfd = socket(sa->sa.sa_family, SOCK_DGRAM, IPPROTO_UDP);
+
+ if(nfd < 0) {
+ logger(LOG_ERR, _("Creating UDP socket failed: %s"), strerror(errno));
+ return -1;
+ }
+
+#ifdef O_NONBLOCK
+ {
+ int flags = fcntl(nfd, F_GETFL);
+
+ if(fcntl(nfd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ closesocket(nfd);
+ logger(LOG_ERR, _("System call `%s' failed: %s"), "fcntl",
+ strerror(errno));
+ return -1;
+ }
+ }
+#endif
+
+ option = 1;
+ setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
+
+#if defined(SOL_IP) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
+ {
+ bool choice;
+
+ if(sa->sa.sa_family == AF_INET && get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
+ option = IP_PMTUDISC_DO;
+ if(setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof(option))) {
+ closesocket(nfd);
+ logger(LOG_ERR, _("Can't set PMTU discovery mode: %s"), strerror(errno));
+ return -1;
+ }
+ }
+ }
+#endif
+
+#if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+ {
+ bool choice;
+
+ if(sa->sa.sa_family == AF_INET6 && get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
+ option = IPV6_PMTUDISC_DO;
+ if(setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof(option))) {
+ closesocket(nfd);
+ logger(LOG_ERR, _("Can't set PMTU discovery mode: %s"), strerror(errno));
+ return -1;
+ }
+ }
+ }