Skip to content

Commit c4b76e5

Browse files
committed
Merge remote-tracking branch 'earl/prot-udp' into master-oldes
2 parents f1870cb + c0053fa commit c4b76e5

File tree

4 files changed

+73
-7
lines changed

4 files changed

+73
-7
lines changed

src/core/c-port.c

+1
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ SCHEME_ACTIONS *Scheme_Actions; // Initial Global (not threaded)
624624
Init_Dir_Scheme();
625625
Init_Event_Scheme();
626626
Init_TCP_Scheme();
627+
Init_UDP_Scheme();
627628
Init_DNS_Scheme();
628629
#ifndef MIN_OS
629630
Init_Clipboard_Scheme();

src/core/p-net.c

+40-4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@
3434

3535
#define NET_BUF_SIZE 32*1024
3636

37+
enum Transport_Types {
38+
TRANSPORT_TCP,
39+
TRANSPORT_UDP
40+
};
41+
3742
/***********************************************************************
3843
**
3944
*/ static void Ret_Query_Net(REBSER *port, REBREQ *sock, REBVAL *ret)
@@ -86,10 +91,9 @@
8691
OS_FREE(nsock); // allocated by dev_net.c (MT issues?)
8792
}
8893

89-
9094
/***********************************************************************
9195
**
92-
*/ static int TCP_Actor(REBVAL *ds, REBSER *port, REBCNT action)
96+
*/ static int Transport_Actor(REBVAL *ds, REBSER *port, REBCNT action, enum Transport_Types proto)
9397
/*
9498
***********************************************************************/
9599
{
@@ -109,6 +113,9 @@
109113
refs = 0;
110114

111115
sock = Use_Port_State(port, RDI_NET, sizeof(*sock));
116+
if (proto == TRANSPORT_UDP) {
117+
SET_FLAG(sock->modes, RST_UDP);
118+
}
112119
//Debug_Fmt("Sock: %x", sock);
113120
spec = OFV(port, STD_PORT_SPEC);
114121
if (!IS_OBJECT(spec)) Trap0(RE_INVALID_PORT);
@@ -189,7 +196,9 @@
189196
// Read data into a buffer, expanding the buffer if needed.
190197
// If no length is given, program must stop it at some point.
191198
refs = Find_Refines(ds, ALL_READ_REFS);
192-
if (!GET_FLAG(sock->state, RSM_CONNECT)) Trap_Port(RE_NOT_CONNECTED, port, -15);
199+
if (!GET_FLAG(sock->modes, RST_UDP)
200+
&& !GET_FLAG(sock->state, RSM_CONNECT))
201+
Trap_Port(RE_NOT_CONNECTED, port, -15);
193202

194203
// Setup the read buffer (allocate a buffer if needed):
195204
arg = OFV(port, STD_PORT_DATA);
@@ -214,7 +223,9 @@
214223
// The lower level write code continues until done.
215224

216225
refs = Find_Refines(ds, ALL_WRITE_REFS);
217-
if (!GET_FLAG(sock->state, RSM_CONNECT)) Trap_Port(RE_NOT_CONNECTED, port, -15);
226+
if (!GET_FLAG(sock->modes, RST_UDP)
227+
&& !GET_FLAG(sock->state, RSM_CONNECT))
228+
Trap_Port(RE_NOT_CONNECTED, port, -15);
218229

219230
// Determine length. Clip /PART to size of string if needed.
220231
spec = D_ARG(2);
@@ -293,6 +304,23 @@
293304
return R_RET;
294305
}
295306

307+
/***********************************************************************
308+
**
309+
*/ static int TCP_Actor(REBVAL *ds, REBSER *port, REBCNT action)
310+
/*
311+
***********************************************************************/
312+
{
313+
return Transport_Actor(ds, port, action, TRANSPORT_TCP);
314+
}
315+
316+
/***********************************************************************
317+
**
318+
*/ static int UDP_Actor(REBVAL *ds, REBSER *port, REBCNT action)
319+
/*
320+
***********************************************************************/
321+
{
322+
return Transport_Actor(ds, port, action, TRANSPORT_UDP);
323+
}
296324

297325
/***********************************************************************
298326
**
@@ -302,3 +330,11 @@
302330
{
303331
Register_Scheme(SYM_TCP, 0, TCP_Actor);
304332
}
333+
/***********************************************************************
334+
**
335+
*/ void Init_UDP_Scheme(void)
336+
/*
337+
***********************************************************************/
338+
{
339+
Register_Scheme(SYM_UDP, 0, UDP_Actor);
340+
}

src/mezz/sys-ports.r

+8
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,14 @@ init-schemes: func [
261261
awake: func [event] [print ['TCP-event event/type] true]
262262
]
263263

264+
make-scheme [
265+
title: "UDP Networking"
266+
name: 'udp
267+
spec: system/standard/port-spec-net
268+
info: system/standard/net-info ; for C enums
269+
awake: func [event] [print ['UDP-event event/type] true]
270+
]
271+
264272
make-scheme [
265273
title: "Clipboard"
266274
name: 'clipboard

src/os/dev-net.c

+24-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ void Signal_Device(REBREQ *req, REBINT type);
5757
DEVICE_CMD Listen_Socket(REBREQ *sock);
5858

5959
#ifdef TO_WIN32
60+
typedef int socklen_t;
6061
extern HWND Event_Handle; // For WSAAsync API
6162
#endif
6263

@@ -356,6 +357,14 @@ static REBOOL Nonblocking_Mode(SOCKET sock)
356357

357358
if (GET_FLAG(sock->state, RSM_CONNECT)) return DR_DONE; // already connected
358359

360+
if (GET_FLAG(sock->modes, RST_UDP)) {
361+
CLR_FLAG(sock->state, RSM_ATTEMPT);
362+
SET_FLAG(sock->state, RSM_CONNECT);
363+
Get_Local_IP(sock);
364+
Signal_Device(sock, EVT_CONNECT);
365+
return DR_DONE; // done
366+
}
367+
359368
Set_Addr(&sa, sock->net.remote_ip, sock->net.remote_port);
360369
result = connect(sock->socket, (struct sockaddr *)&sa, sizeof(sa));
361370

@@ -422,9 +431,12 @@ static REBOOL Nonblocking_Mode(SOCKET sock)
422431
{
423432
int result;
424433
long len;
434+
SOCKAI remote_addr;
435+
socklen_t addr_len = sizeof(remote_addr);
425436
int mode = (sock->command == RDC_READ ? RSM_RECEIVE : RSM_SEND);
426437

427-
if (!GET_FLAG(sock->state, RSM_CONNECT)) {
438+
if (!GET_FLAG(sock->state, RSM_CONNECT)
439+
&& !GET_FLAG(sock->modes, RST_UDP)) {
428440
sock->error = -18;
429441
return DR_ERROR;
430442
}
@@ -436,7 +448,11 @@ static REBOOL Nonblocking_Mode(SOCKET sock)
436448

437449
if (mode == RSM_SEND) {
438450
// If host is no longer connected:
439-
result = send(sock->socket, sock->data, len, 0);
451+
if (GET_FLAG(sock->modes, RST_UDP)) {
452+
Set_Addr(&remote_addr, sock->net.remote_ip, sock->net.remote_port);
453+
}
454+
result = sendto(sock->socket, sock->data, len, 0,
455+
(struct sockaddr*)&remote_addr, addr_len);
440456
WATCH2("send() len: %d actual: %d\n", len, result);
441457

442458
if (result >= 0) {
@@ -451,10 +467,15 @@ static REBOOL Nonblocking_Mode(SOCKET sock)
451467
// if (result < 0) ...
452468
}
453469
else {
454-
result = recv(sock->socket, sock->data, len, 0);
470+
result = recvfrom(sock->socket, sock->data, len, 0,
471+
(struct sockaddr*)&remote_addr, &addr_len);
455472
WATCH2("recv() len: %d result: %d\n", len, result);
456473

457474
if (result > 0) {
475+
if (GET_FLAG(sock->modes, RST_UDP)) {
476+
sock->net.remote_ip = remote_addr.sin_addr.s_addr;
477+
sock->net.remote_port = ntohs(remote_addr.sin_port);
478+
}
458479
sock->actual = result;
459480
Signal_Device(sock, EVT_READ);
460481
return DR_DONE;

0 commit comments

Comments
 (0)