Skip to content

Commit 3b83aeb

Browse files
committed
unix: modsocket: Implement sendto().
sendto() turns out to be mandatory function to work with UDP. It may seem that connect(addr) + send() would achieve the same effect, but what connect() appears to do is to set source address filter on a socket to its argument. Then everything falls apart: socket sends to a broad-/multi-cast address, but reply is sent from real peer address, which doesn't match filter set by connect(), so local socket never sees a reply.
1 parent 115afdb commit 3b83aeb

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

unix/modsocket.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,27 @@ STATIC mp_obj_t socket_send(mp_uint_t n_args, const mp_obj_t *args) {
206206
}
207207
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_send_obj, 2, 3, socket_send);
208208

209+
STATIC mp_obj_t socket_sendto(mp_uint_t n_args, const mp_obj_t *args) {
210+
mp_obj_socket_t *self = args[0];
211+
int flags = 0;
212+
213+
mp_obj_t dst_addr = args[2];
214+
if (n_args > 3) {
215+
flags = MP_OBJ_SMALL_INT_VALUE(args[2]);
216+
dst_addr = args[3];
217+
}
218+
219+
mp_buffer_info_t bufinfo, addr_bi;
220+
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
221+
mp_get_buffer_raise(dst_addr, &addr_bi, MP_BUFFER_READ);
222+
int out_sz = sendto(self->fd, bufinfo.buf, bufinfo.len, flags,
223+
(struct sockaddr *)addr_bi.buf, addr_bi.len);
224+
RAISE_ERRNO(out_sz, errno);
225+
226+
return MP_OBJ_NEW_SMALL_INT(out_sz);
227+
}
228+
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socket_sendto_obj, 3, 4, socket_sendto);
229+
209230
STATIC mp_obj_t socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) {
210231
(void)n_args; // always 4
211232
mp_obj_socket_t *self = args[0];
@@ -300,6 +321,7 @@ STATIC const mp_map_elem_t usocket_locals_dict_table[] = {
300321
{ MP_OBJ_NEW_QSTR(MP_QSTR_accept), (mp_obj_t)&socket_accept_obj },
301322
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&socket_recv_obj },
302323
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&socket_send_obj },
324+
{ MP_OBJ_NEW_QSTR(MP_QSTR_sendto), (mp_obj_t)&socket_sendto_obj },
303325
{ MP_OBJ_NEW_QSTR(MP_QSTR_setsockopt), (mp_obj_t)&socket_setsockopt_obj },
304326
{ MP_OBJ_NEW_QSTR(MP_QSTR_setblocking), (mp_obj_t)&socket_setblocking_obj },
305327
{ MP_OBJ_NEW_QSTR(MP_QSTR_close), (mp_obj_t)&socket_close_obj },

unix/qstrdefsport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ Q(bind)
7070
Q(listen)
7171
Q(accept)
7272
Q(recv)
73+
Q(sendto)
7374
Q(setsockopt)
7475
Q(setblocking)
7576

0 commit comments

Comments
 (0)