Hi, I'm trying to make my iPhone work with IPv6, I can't find any details on anyconnect using ipv6, so I just try to debug and make some changes on ocserv. I need someone tell me if I was in a wrong track or ocserv ipv6 is buggy. I asked Linode for an ipv6 address pool, set the options like ipv6-network = 2400:8900:e000:xxxx:: ipv6-prefix = 64 But clients generate fake IPv6 addresses(Debug logs in AnyConnect iOS). I add debug log in cstp_send(), see what's sent to the client, no IPv6 address found, but in the debug log: ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 new cookie for 'sskaje' (1359) ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 accepting user 'sskaje' ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 selected IP for 'sskaje': 192.168.122.198 ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 selected IP for 'sskaje': 2400:8900:e000:xxxx:xxxx:2f:f9e5:c700 ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 assigned IPv4 to 'sskaje': 192.168.122.199 ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 assigned IPv6 to 'sskaje': 2400:8900:e000:xxxx:xxxx:2f:f9e5:c701 ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 assigning tun device vpns0 ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 user 'sskaje' of group 'vpn' authenticated (using cookie) ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 sending dns '8.8.8.8' ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 sending dns '8.8.8.8' ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 sending dns '8.8.4.4' ocserv[1351]: main[sskaje]: xx.xx.xx.xx:12651 sending (socket) message 2 to worker ifconfig on my Ubuntu VPS, the c700 IP is assigned to the vpns0, but c701 not ping6-able. In worker-vpn.c, I found if (ws->vinfo.ipv6 && req->no_ipv6 == 0) { has no_ipv6 == 1, So I added extra User Agent matching like: if (strncasecmp(req->user_agent, "Open Any", 8) == 0) { if (strncmp(req->user_agent, "Open AnyConnect VPN Agent v3", 28) == 0) req->user_agent_type = AGENT_OPENCONNECT_V3; else req->user_agent_type = AGENT_OPENCONNECT; } else if (strncasecmp(req->user_agent, "Cisco AnyConnect", 16) == 0) { req->user_agent_type = AGENT_ANYCONNECT; } break; And then /* If we are in CISCO client compatibility mode, do not send * any IPv6 information, unless the client can really handle it. */ if (ws->full_ipv6 == 0 && ws->config->cisco_client_compat != 0 && req->user_agent_type != AGENT_OPENCONNECT && req->user_agent_type != AGENT_ANYCONNECT) { req->no_ipv6 = 1; } But ws->full_ipv6 is still 0, and TWO X-CSTP-Address lines are sent to client, with both IPv4 and IPv6 addresses. Logs: ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: HTTP/1.1 200 CONNECTED ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Version: 1 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-Server-Version: ocserv 0.8.9 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-DPD: 90 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Default-Domain: sskaje.me ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Address: 192.168.122.199 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Netmask: 255.255.255.0 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Address: 2400:8900:e000:xxxx:xxxx:2f:f9e5:c701 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-DNS: 8.8.8.8 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-DNS: 8.8.8.8 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-DNS: 8.8.4.4 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Keepalive: 32400 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Idle-Timeout: none ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Smartcard-Removal-Disconnect: true ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Rekey-Time: 172800 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Rekey-Method: ssl ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Session-Timeout: none ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-Base-MTU: 1435 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-DTLS-Session-ID: -------- ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-DTLS-DPD: 90 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-DTLS-Port: 8443 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-DTLS-Rekey-Time: 172810 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-DTLS-Rekey-Method: ssl ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-DTLS-Keepalive: 32400 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-DTLS-CipherSuite: AES128-SHA ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-DTLS-MTU: 1341 ocserv[21790]: worker[sskaje]: xx.xx.xx.xx:54901 ========HTTP_HEADER: X-CSTP-MTU: 1341 I guess if it is because the full_ipv6 0, then I force it 1 for AnyConnect: if (req->user_agent_type == AGENT_ANYCONNECT) { ws->full_ipv6 = 1; } found ws->vinfo.ipv6_prefix == 0, fixed in worker-auth.c: static int recv_cookie_auth_reply(worker_st * ws) ... if (msg->ipv6_prefix) { ws->config->network.ipv6_prefix = msg->ipv6_prefix; } ... And the ws->vinfo.ipv6_network is also null, from recv_cookie_auth_reply() both ws->config->network.ipv6_network and msg->ipv6_prefix are null. In config.c, ipv6-network options is read into config->network.ipv6. I'm totally lost. sskaje at gmail.com https://sskaje.me/