+int setup_vpn_in_socket(const sockaddr_t *sa) {
+ 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;
+ }
+ }
+#elif defined(WIN32)
+ {
+ unsigned long arg = 1;
+ if(ioctlsocket(nfd, FIONBIO, &arg) != 0) {
+ closesocket(nfd);
+ logger(LOG_ERR, _("Call to `%s' failed: WSA error %d"), "ioctlsocket",
+ WSAGetLastError());
+ 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(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
+ option = IP_PMTUDISC_DO;
+ setsockopt(nfd, SOL_IP, IP_MTU_DISCOVER, &option, sizeof(option));
+ }
+ }
+#endif
+
+#if defined(SOL_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
+ {
+ bool choice;
+
+ if(get_config_bool(lookup_config(myself->connection->config_tree, "PMTUDiscovery"), &choice) && choice) {
+ option = IPV6_PMTUDISC_DO;
+ setsockopt(nfd, SOL_IPV6, IPV6_MTU_DISCOVER, &option, sizeof(option));
+ }
+ }