| 832 | } |
| 833 | |
| 834 | int |
| 835 | lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) |
| 836 | { |
| 837 | struct lwip_sock *sock; |
| 838 | err_t err; |
| 839 | |
| 840 | sock = get_socket(s); |
| 841 | if (!sock) { |
| 842 | return -1; |
| 843 | } |
| 844 | |
| 845 | if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { |
| 846 | /* sockaddr does not match socket type (IPv4/IPv6) */ |
| 847 | sock_set_errno(sock, err_to_errno(ERR_VAL)); |
| 848 | done_socket(sock); |
| 849 | return -1; |
| 850 | } |
| 851 | |
| 852 | LWIP_UNUSED_ARG(namelen); |
| 853 | if (name->sa_family == AF_UNSPEC) { |
| 854 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); |
| 855 | err = netconn_disconnect(sock->conn); |
| 856 | } else { |
| 857 | ip_addr_t remote_addr; |
| 858 | u16_t remote_port; |
| 859 | |
| 860 | /* check size, family and alignment of 'name' */ |
| 861 | LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) && |
| 862 | IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name), |
| 863 | sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); |
| 864 | |
| 865 | SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port); |
| 866 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); |
| 867 | ip_addr_debug_print_val(SOCKETS_DEBUG, remote_addr); |
| 868 | LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port)); |
| 869 | |
| 870 | #if LWIP_IPV4 && LWIP_IPV6 |
| 871 | /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ |
| 872 | if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) { |
| 873 | unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr)); |
| 874 | IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4); |
| 875 | } |
| 876 | #endif /* LWIP_IPV4 && LWIP_IPV6 */ |
| 877 | |
| 878 | err = netconn_connect(sock->conn, &remote_addr, remote_port); |
| 879 | } |
| 880 | |
| 881 | if (err != ERR_OK) { |
| 882 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); |
| 883 | sock_set_errno(sock, err_to_errno(err)); |
| 884 | done_socket(sock); |
| 885 | return -1; |
| 886 | } |
| 887 | |
| 888 | LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); |
| 889 | sock_set_errno(sock, 0); |
| 890 | done_socket(sock); |
| 891 | return 0; |