|
|
@@ -3,7 +3,7 @@
|
|
|
*
|
|
|
* The MIT License (MIT)
|
|
|
*
|
|
|
- * Copyright (c) 2014 Damien P. George
|
|
|
+ * Copyright (c) 2018 Armink (armink.ztl@gmail.com)
|
|
|
*
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
|
@@ -34,6 +34,11 @@
|
|
|
#include "lib/netutils/netutils.h"
|
|
|
#include "modnetwork.h"
|
|
|
|
|
|
+#include <stdio.h>
|
|
|
+#include <netdb.h>
|
|
|
+#include <sys/socket.h>
|
|
|
+#include <dfs_posix.h>
|
|
|
+
|
|
|
#if MICROPY_PY_USOCKET
|
|
|
|
|
|
/******************************************************************************/
|
|
|
@@ -41,69 +46,66 @@
|
|
|
|
|
|
STATIC const mp_obj_type_t socket_type;
|
|
|
|
|
|
-// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
|
|
|
+typedef struct _posix_socket_obj_t {
|
|
|
+ mp_obj_base_t base;
|
|
|
+ int fd;
|
|
|
+} posix_socket_obj_t;
|
|
|
+
|
|
|
+// constructor socket(family=AF_INET, type=SOCK_STREAM, proto=0)
|
|
|
STATIC mp_obj_t socket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
|
|
+ uint8_t domain = AF_INET;
|
|
|
+ uint8_t style = SOCK_STREAM;
|
|
|
+ uint8_t proto = 0;
|
|
|
+ int fd = -1;
|
|
|
+ posix_socket_obj_t *s = MP_OBJ_NULL;
|
|
|
+
|
|
|
mp_arg_check_num(n_args, n_kw, 0, 4, false);
|
|
|
|
|
|
- // create socket object (not bound to any NIC yet)
|
|
|
- mod_network_socket_obj_t *s = m_new_obj_with_finaliser(mod_network_socket_obj_t);
|
|
|
s->base.type = (mp_obj_t)&socket_type;
|
|
|
- s->nic = MP_OBJ_NULL;
|
|
|
- s->nic_type = NULL;
|
|
|
- s->u_param.domain = MOD_NETWORK_AF_INET;
|
|
|
- s->u_param.type = MOD_NETWORK_SOCK_STREAM;
|
|
|
- s->u_param.fileno = -1;
|
|
|
+
|
|
|
if (n_args >= 1) {
|
|
|
- s->u_param.domain = mp_obj_get_int(args[0]);
|
|
|
+ domain = mp_obj_get_int(args[0]);
|
|
|
if (n_args >= 2) {
|
|
|
- s->u_param.type = mp_obj_get_int(args[1]);
|
|
|
- if (n_args >= 4) {
|
|
|
- s->u_param.fileno = mp_obj_get_int(args[3]);
|
|
|
- }
|
|
|
+ style = mp_obj_get_int(args[1]);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return s;
|
|
|
-}
|
|
|
-
|
|
|
-STATIC void socket_select_nic(mod_network_socket_obj_t *self, const byte *ip) {
|
|
|
- if (self->nic == MP_OBJ_NULL) {
|
|
|
- // select NIC based on IP
|
|
|
- self->nic = mod_network_find_nic(ip);
|
|
|
- self->nic_type = (mod_network_nic_type_t*)mp_obj_get_type(self->nic);
|
|
|
+ fd = socket(domain, style, proto);
|
|
|
|
|
|
- // call the NIC to open the socket
|
|
|
- int _errno;
|
|
|
- if (self->nic_type->socket(self, &_errno) != 0) {
|
|
|
- mp_raise_OSError(_errno);
|
|
|
+ if (fd != -1) {
|
|
|
+ s = m_new_obj_with_finaliser(posix_socket_obj_t);
|
|
|
+ if (s) {
|
|
|
+ s->fd = fd;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ return s;
|
|
|
}
|
|
|
+
|
|
|
// method socket.close()
|
|
|
STATIC mp_obj_t socket_close(mp_obj_t self_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
- if (self->nic != MP_OBJ_NULL) {
|
|
|
- self->nic_type->close(self);
|
|
|
- self->nic = MP_OBJ_NULL;
|
|
|
- }
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
+
|
|
|
+ closesocket(self->fd);
|
|
|
+
|
|
|
return mp_const_none;
|
|
|
}
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_close_obj, socket_close);
|
|
|
|
|
|
// method socket.bind(address)
|
|
|
STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
-
|
|
|
- // get address
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
+ int _errno;
|
|
|
uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
|
|
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG);
|
|
|
+ struct sockaddr_in sockaddr;
|
|
|
|
|
|
- // check if we need to select a NIC
|
|
|
- socket_select_nic(self, ip);
|
|
|
+ sockaddr.sin_family = AF_INET;
|
|
|
+ sockaddr.sin_port = htons(port);
|
|
|
+ inet_aton((char *)ip, (struct in_addr* )&(sockaddr.sin_addr));
|
|
|
+ memset(&(sockaddr.sin_zero), 0, sizeof(sockaddr.sin_zero));
|
|
|
|
|
|
- // call the NIC to bind the socket
|
|
|
- int _errno;
|
|
|
- if (self->nic_type->bind(self, ip, port, &_errno) != 0) {
|
|
|
+ if ((_errno = bind(self->fd, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr))) < 0) {
|
|
|
mp_raise_OSError(_errno);
|
|
|
}
|
|
|
|
|
|
@@ -113,16 +115,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_bind_obj, socket_bind);
|
|
|
|
|
|
// method socket.listen(backlog)
|
|
|
STATIC mp_obj_t socket_listen(mp_obj_t self_in, mp_obj_t backlog) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
-
|
|
|
- if (self->nic == MP_OBJ_NULL) {
|
|
|
- // not connected
|
|
|
- // TODO I think we can listen even if not bound...
|
|
|
- mp_raise_OSError(MP_ENOTCONN);
|
|
|
- }
|
|
|
-
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
int _errno;
|
|
|
- if (self->nic_type->listen(self, mp_obj_get_int(backlog), &_errno) != 0) {
|
|
|
+
|
|
|
+ if ((_errno = listen(self->fd, mp_obj_get_int(backlog))) < 0) {
|
|
|
mp_raise_OSError(_errno);
|
|
|
}
|
|
|
|
|
|
@@ -132,31 +128,25 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_listen_obj, socket_listen);
|
|
|
|
|
|
// method socket.accept()
|
|
|
STATIC mp_obj_t socket_accept(mp_obj_t self_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
|
|
|
// create new socket object
|
|
|
- // starts with empty NIC so that finaliser doesn't run close() method if accept() fails
|
|
|
- mod_network_socket_obj_t *socket2 = m_new_obj_with_finaliser(mod_network_socket_obj_t);
|
|
|
+ posix_socket_obj_t *socket2 = m_new_obj_with_finaliser(posix_socket_obj_t);
|
|
|
socket2->base.type = (mp_obj_t)&socket_type;
|
|
|
- socket2->nic = MP_OBJ_NULL;
|
|
|
- socket2->nic_type = NULL;
|
|
|
|
|
|
// accept incoming connection
|
|
|
- uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
|
|
- mp_uint_t port;
|
|
|
- int _errno;
|
|
|
- if (self->nic_type->accept(self, socket2, ip, &port, &_errno) != 0) {
|
|
|
- mp_raise_OSError(_errno);
|
|
|
- }
|
|
|
+ int new_client;
|
|
|
+ struct sockaddr_in addr;
|
|
|
+ socklen_t addrlen;
|
|
|
|
|
|
- // new socket has valid state, so set the NIC to the same as parent
|
|
|
- socket2->nic = self->nic;
|
|
|
- socket2->nic_type = self->nic_type;
|
|
|
+ if ((new_client = accept(self->fd, (struct sockaddr *)&addr, &addrlen)) < 0) {
|
|
|
+ mp_raise_OSError(new_client);
|
|
|
+ }
|
|
|
|
|
|
// make the return value
|
|
|
mp_obj_tuple_t *client = mp_obj_new_tuple(2, NULL);
|
|
|
client->items[0] = socket2;
|
|
|
- client->items[1] = netutils_format_inet_addr(ip, port, NETUTILS_BIG);
|
|
|
+ client->items[1] = netutils_format_inet_addr((uint8_t *)inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), NETUTILS_BIG);
|
|
|
|
|
|
return client;
|
|
|
}
|
|
|
@@ -164,18 +154,20 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_accept_obj, socket_accept);
|
|
|
|
|
|
// method socket.connect(address)
|
|
|
STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
|
|
|
// get address
|
|
|
uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
|
|
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG);
|
|
|
|
|
|
- // check if we need to select a NIC
|
|
|
- socket_select_nic(self, ip);
|
|
|
-
|
|
|
- // call the NIC to connect the socket
|
|
|
int _errno;
|
|
|
- if (self->nic_type->connect(self, ip, port, &_errno) != 0) {
|
|
|
+ struct sockaddr_in sockaddr;
|
|
|
+ sockaddr.sin_family = AF_INET;
|
|
|
+ sockaddr.sin_port = htons(port);
|
|
|
+ inet_aton((char *)ip, (struct in_addr* )&(sockaddr.sin_addr));
|
|
|
+ memset(&(sockaddr.sin_zero), 0, sizeof(sockaddr.sin_zero));
|
|
|
+
|
|
|
+ if ((_errno = connect(self->fd, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr))) <= 0) {
|
|
|
mp_raise_OSError(_errno);
|
|
|
}
|
|
|
|
|
|
@@ -185,36 +177,30 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect);
|
|
|
|
|
|
// method socket.send(bytes)
|
|
|
STATIC mp_obj_t socket_send(mp_obj_t self_in, mp_obj_t buf_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
- if (self->nic == MP_OBJ_NULL) {
|
|
|
- // not connected
|
|
|
- mp_raise_OSError(MP_EPIPE);
|
|
|
- }
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
mp_buffer_info_t bufinfo;
|
|
|
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
|
|
int _errno;
|
|
|
- mp_uint_t ret = self->nic_type->send(self, bufinfo.buf, bufinfo.len, &_errno);
|
|
|
- if (ret == -1) {
|
|
|
+
|
|
|
+ _errno = send(self->fd, bufinfo.buf, bufinfo.len, 0);
|
|
|
+ if (_errno == -1) {
|
|
|
mp_raise_OSError(_errno);
|
|
|
}
|
|
|
- return mp_obj_new_int_from_uint(ret);
|
|
|
+ return mp_obj_new_int_from_uint(_errno);
|
|
|
}
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_send_obj, socket_send);
|
|
|
|
|
|
// method socket.recv(bufsize)
|
|
|
STATIC mp_obj_t socket_recv(mp_obj_t self_in, mp_obj_t len_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
- if (self->nic == MP_OBJ_NULL) {
|
|
|
- // not connected
|
|
|
- mp_raise_OSError(MP_ENOTCONN);
|
|
|
- }
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
mp_int_t len = mp_obj_get_int(len_in);
|
|
|
vstr_t vstr;
|
|
|
vstr_init_len(&vstr, len);
|
|
|
- int _errno;
|
|
|
- mp_uint_t ret = self->nic_type->recv(self, (byte*)vstr.buf, len, &_errno);
|
|
|
+ int ret;
|
|
|
+
|
|
|
+ ret = recv(self->fd, (byte*)vstr.buf, len, 0);
|
|
|
if (ret == -1) {
|
|
|
- mp_raise_OSError(_errno);
|
|
|
+ mp_raise_OSError(ret);
|
|
|
}
|
|
|
if (ret == 0) {
|
|
|
return mp_const_empty_bytes;
|
|
|
@@ -226,7 +212,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recv_obj, socket_recv);
|
|
|
|
|
|
// method socket.sendto(bytes, address)
|
|
|
STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
|
|
|
// get the data
|
|
|
mp_buffer_info_t bufinfo;
|
|
|
@@ -235,15 +221,15 @@ STATIC mp_obj_t socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_
|
|
|
// get address
|
|
|
uint8_t ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
|
|
mp_uint_t port = netutils_parse_inet_addr(addr_in, ip, NETUTILS_BIG);
|
|
|
+ struct sockaddr_in sockaddr;
|
|
|
+ sockaddr.sin_family = AF_INET;
|
|
|
+ sockaddr.sin_port = htons(port);
|
|
|
+ inet_aton((char *)ip, (struct in_addr* )&(sockaddr.sin_addr));
|
|
|
+ memset(&(sockaddr.sin_zero), 0, sizeof(sockaddr.sin_zero));
|
|
|
|
|
|
- // check if we need to select a NIC
|
|
|
- socket_select_nic(self, ip);
|
|
|
-
|
|
|
- // call the NIC to sendto
|
|
|
- int _errno;
|
|
|
- mp_int_t ret = self->nic_type->sendto(self, bufinfo.buf, bufinfo.len, ip, port, &_errno);
|
|
|
+ mp_int_t ret = sendto(self->fd, bufinfo.buf, bufinfo.len, MSG_DONTWAIT, (struct sockaddr *)&sockaddr, sizeof(struct sockaddr));
|
|
|
if (ret == -1) {
|
|
|
- mp_raise_OSError(_errno);
|
|
|
+ mp_raise_OSError(ret);
|
|
|
}
|
|
|
|
|
|
return mp_obj_new_int(ret);
|
|
|
@@ -252,19 +238,22 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(socket_sendto_obj, socket_sendto);
|
|
|
|
|
|
// method socket.recvfrom(bufsize)
|
|
|
STATIC mp_obj_t socket_recvfrom(mp_obj_t self_in, mp_obj_t len_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
- if (self->nic == MP_OBJ_NULL) {
|
|
|
- // not connected
|
|
|
- mp_raise_OSError(MP_ENOTCONN);
|
|
|
- }
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
vstr_t vstr;
|
|
|
vstr_init_len(&vstr, mp_obj_get_int(len_in));
|
|
|
byte ip[4];
|
|
|
mp_uint_t port;
|
|
|
- int _errno;
|
|
|
- mp_int_t ret = self->nic_type->recvfrom(self, (byte*)vstr.buf, vstr.len, ip, &port, &_errno);
|
|
|
+ int ret;
|
|
|
+ struct sockaddr_in sockaddr;
|
|
|
+ uint32_t addr_len;
|
|
|
+ sockaddr.sin_family = AF_INET;
|
|
|
+ sockaddr.sin_port = htons(port);
|
|
|
+ inet_aton((char *)ip, (struct in_addr* )&(sockaddr.sin_addr));
|
|
|
+ memset(&(sockaddr.sin_zero), 0, sizeof(sockaddr.sin_zero));
|
|
|
+
|
|
|
+ ret = recvfrom(self->fd, vstr.buf, vstr.len, MSG_DONTWAIT, (struct sockaddr *)&sockaddr, &addr_len);
|
|
|
if (ret == -1) {
|
|
|
- mp_raise_OSError(_errno);
|
|
|
+ mp_raise_OSError(ret);
|
|
|
}
|
|
|
mp_obj_t tuple[2];
|
|
|
if (ret == 0) {
|
|
|
@@ -280,7 +269,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_recvfrom_obj, socket_recvfrom);
|
|
|
|
|
|
// method socket.setsockopt(level, optname, value)
|
|
|
STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
|
|
- mod_network_socket_obj_t *self = args[0];
|
|
|
+ posix_socket_obj_t *self = args[0];
|
|
|
|
|
|
mp_int_t level = mp_obj_get_int(args[1]);
|
|
|
mp_int_t opt = mp_obj_get_int(args[2]);
|
|
|
@@ -300,7 +289,7 @@ STATIC mp_obj_t socket_setsockopt(size_t n_args, const mp_obj_t *args) {
|
|
|
}
|
|
|
|
|
|
int _errno;
|
|
|
- if (self->nic_type->setsockopt(self, level, opt, optval, optlen, &_errno) != 0) {
|
|
|
+ if ((_errno = setsockopt(self->fd, level, opt, optval, optlen)) < 0) {
|
|
|
mp_raise_OSError(_errno);
|
|
|
}
|
|
|
|
|
|
@@ -313,12 +302,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_setsockopt_obj, 4, 4, socket_s
|
|
|
// timeout=None means blocking
|
|
|
// otherwise, timeout is in seconds
|
|
|
STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
- if (self->nic == MP_OBJ_NULL) {
|
|
|
- // not connected
|
|
|
- mp_raise_OSError(MP_ENOTCONN);
|
|
|
- }
|
|
|
- mp_uint_t timeout;
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
+ int timeout;
|
|
|
+
|
|
|
if (timeout_in == mp_const_none) {
|
|
|
timeout = -1;
|
|
|
} else {
|
|
|
@@ -329,7 +315,18 @@ STATIC mp_obj_t socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) {
|
|
|
#endif
|
|
|
}
|
|
|
int _errno;
|
|
|
- if (self->nic_type->settimeout(self, timeout, &_errno) != 0) {
|
|
|
+
|
|
|
+ int flags = ioctl(self->fd, F_GETFL, NULL);
|
|
|
+ if (timeout < 0) {
|
|
|
+ _errno = ioctl(self->fd, F_SETFL, (void *)(flags & (~O_NONBLOCK)));
|
|
|
+ } else if (timeout > 0) {
|
|
|
+ //TODO
|
|
|
+ MP_RTT_NOT_IMPL_PRINT;
|
|
|
+ } else {
|
|
|
+ _errno = ioctl(self->fd, F_SETFL, (void *)(flags | O_NONBLOCK));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_errno < 0) {
|
|
|
mp_raise_OSError(_errno);
|
|
|
}
|
|
|
return mp_const_none;
|
|
|
@@ -365,8 +362,9 @@ STATIC const mp_rom_map_elem_t socket_locals_dict_table[] = {
|
|
|
STATIC MP_DEFINE_CONST_DICT(socket_locals_dict, socket_locals_dict_table);
|
|
|
|
|
|
mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
|
|
|
- mod_network_socket_obj_t *self = self_in;
|
|
|
- return self->nic_type->ioctl(self, request, arg, errcode);
|
|
|
+ posix_socket_obj_t *self = self_in;
|
|
|
+
|
|
|
+ return ioctl(self->fd, request, (void *)arg);
|
|
|
}
|
|
|
|
|
|
STATIC const mp_stream_p_t socket_stream_p = {
|
|
|
@@ -389,40 +387,21 @@ STATIC const mp_obj_type_t socket_type = {
|
|
|
STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
|
|
|
size_t hlen;
|
|
|
const char *host = mp_obj_str_get_data(host_in, &hlen);
|
|
|
+ const char port_in_s[6] = { 0 };
|
|
|
mp_int_t port = mp_obj_get_int(port_in);
|
|
|
- uint8_t out_ip[MOD_NETWORK_IPADDR_BUF_SIZE];
|
|
|
- bool have_ip = false;
|
|
|
-
|
|
|
- if (hlen > 0) {
|
|
|
- // check if host is already in IP form
|
|
|
- nlr_buf_t nlr;
|
|
|
- if (nlr_push(&nlr) == 0) {
|
|
|
- netutils_parse_ipv4_addr(host_in, out_ip, NETUTILS_BIG);
|
|
|
- have_ip = true;
|
|
|
- nlr_pop();
|
|
|
- } else {
|
|
|
- // swallow exception: host was not in IP form so need to do DNS lookup
|
|
|
- }
|
|
|
- }
|
|
|
+ int ret;
|
|
|
|
|
|
- if (!have_ip) {
|
|
|
- // find a NIC that can do a name lookup
|
|
|
- for (mp_uint_t i = 0; i < MP_STATE_PORT(mod_network_nic_list).len; i++) {
|
|
|
- mp_obj_t nic = MP_STATE_PORT(mod_network_nic_list).items[i];
|
|
|
- mod_network_nic_type_t *nic_type = (mod_network_nic_type_t*)mp_obj_get_type(nic);
|
|
|
- if (nic_type->gethostbyname != NULL) {
|
|
|
- int ret = nic_type->gethostbyname(nic, host, hlen, out_ip);
|
|
|
- if (ret != 0) {
|
|
|
- mp_raise_OSError(ret);
|
|
|
- }
|
|
|
- have_ip = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ snprintf(port_in_s, sizeof(port_in_s), "%d", port);
|
|
|
+
|
|
|
+ struct sockaddr_in sockaddr, *res = NULL;
|
|
|
+ sockaddr.sin_family = AF_INET;
|
|
|
+ sockaddr.sin_port = htons(port);
|
|
|
+ memset(&(sockaddr.sin_zero), 0, sizeof(sockaddr.sin_zero));
|
|
|
|
|
|
- if (!have_ip) {
|
|
|
- nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available NIC"));
|
|
|
+ ret = getaddrinfo(host, port_in_s, &sockaddr, &res);
|
|
|
+
|
|
|
+ if (!ret) {
|
|
|
+ nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "no available netif"));
|
|
|
}
|
|
|
|
|
|
mp_obj_tuple_t *tuple = mp_obj_new_tuple(5, NULL);
|
|
|
@@ -430,7 +409,10 @@ STATIC mp_obj_t mod_usocket_getaddrinfo(mp_obj_t host_in, mp_obj_t port_in) {
|
|
|
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(MOD_NETWORK_SOCK_STREAM);
|
|
|
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(0);
|
|
|
tuple->items[3] = MP_OBJ_NEW_QSTR(MP_QSTR_);
|
|
|
- tuple->items[4] = netutils_format_inet_addr(out_ip, port, NETUTILS_BIG);
|
|
|
+ tuple->items[4] = netutils_format_inet_addr((uint8_t *)inet_ntoa(res->sin_addr), res->sin_port, NETUTILS_BIG);
|
|
|
+
|
|
|
+ freeaddrinfo(res);
|
|
|
+
|
|
|
return mp_obj_new_list(1, (mp_obj_t*)&tuple);
|
|
|
}
|
|
|
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_usocket_getaddrinfo_obj, mod_usocket_getaddrinfo);
|