Skip to content

Commit 0992755

Browse files
committed
FEAT: implemented query/mode on network ports
related to: Oldes/Rebol-issues#1712
1 parent da4f114 commit 0992755

File tree

3 files changed

+112
-11
lines changed

3 files changed

+112
-11
lines changed

src/core/p-net.c

+92-10
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,99 @@ enum Transport_Types {
4242

4343
/***********************************************************************
4444
**
45-
*/ static void Ret_Query_Net(REBSER *port, REBREQ *sock, REBVAL *ret)
45+
*/ static REBOOL Set_Net_Mode_Value(REBREQ *sock, REBCNT mode, REBVAL *ret)
46+
/*
47+
** Set a value with net data according specified mode
48+
**
49+
***********************************************************************/
50+
{
51+
switch (mode) {
52+
case SYM_REMOTE_IP:
53+
Set_Tuple(ret, (REBYTE *)&sock->net.remote_ip, 4);
54+
break;
55+
case SYM_REMOTE_PORT:
56+
SET_INTEGER(ret, sock->net.remote_port);
57+
break;
58+
case SYM_LOCAL_IP:
59+
Set_Tuple(ret, (REBYTE *)&sock->net.local_ip, 4);
60+
break;
61+
case SYM_LOCAL_PORT:
62+
SET_INTEGER(ret, sock->net.local_port);
63+
break;
64+
default:
65+
return FALSE;
66+
}
67+
return TRUE;
68+
}
69+
70+
/***********************************************************************
71+
**
72+
*/ static void Ret_Query_Net(REBSER *port, REBREQ *sock, REBVAL *ret, REBVAL *info)
4673
/*
4774
***********************************************************************/
4875
{
49-
REBVAL *info = In_Object(port, STD_PORT_SCHEME, STD_SCHEME_INFO, 0);
5076
REBSER *obj;
77+
REBVAL *val;
78+
79+
if (IS_WORD(info)) {
80+
if (!Set_Net_Mode_Value(sock, VAL_WORD_CANON(info), ret))
81+
Trap1(RE_INVALID_ARG, info);
82+
}
83+
else if (IS_BLOCK(info)) {
84+
// example:
85+
// query/mode port [remote-ip remote-port] ;== [127.0.0.1 1234]
86+
// or:
87+
// query/mode port [remote-ip: remote-port:] ;== [remote-ip: 127.0.0.1 remote-port: 1234]
88+
// or combined:
89+
// query/mode file [remote-ip: remote-port] ;== [remote-ip: 127.0.0.1 1234]
90+
// When not supported word is used, if will throw an error
91+
92+
REBSER *values = Make_Block(2 * BLK_LEN(VAL_SERIES(info)));
93+
REBVAL *word = VAL_BLK_DATA(info);
94+
for (; NOT_END(word); word++) {
95+
if (ANY_WORD(word)) {
96+
if (IS_SET_WORD(word)) {
97+
// keep the set-word in result
98+
val = Append_Value(values);
99+
*val = *word;
100+
VAL_SET_LINE(val);
101+
}
102+
val = Append_Value(values);
103+
if (!Set_Net_Mode_Value(sock, VAL_WORD_CANON(word), val))
104+
Trap1(RE_INVALID_ARG, word);
105+
}
106+
else Trap1(RE_INVALID_ARG, word);
107+
}
108+
Set_Series(REB_BLOCK, ret, values);
109+
}
110+
else {
111+
//@@ oldes: is returning object really still needed?
112+
info = In_Object(port, STD_PORT_SCHEME, STD_SCHEME_INFO, 0);
51113

52-
if (!info || !IS_OBJECT(info)) Trap_Port(RE_INVALID_SPEC, port, -10);
114+
if (!info || !IS_OBJECT(info)) {
115+
Trap_Port(RE_INVALID_SPEC, port, -10);
116+
return; // prevents compiler's warning
117+
}
53118

54-
obj = CLONE_OBJECT(VAL_OBJ_FRAME(info));
119+
obj = CLONE_OBJECT(VAL_OBJ_FRAME(info));
55120

56-
SET_OBJECT(ret, obj);
57-
Set_Tuple(OFV(obj, STD_NET_INFO_LOCAL_IP), (REBYTE*)&sock->net.local_ip, 4);
58-
Set_Tuple(OFV(obj, STD_NET_INFO_REMOTE_IP), (REBYTE*)&sock->net.remote_ip, 4);
59-
SET_INTEGER(OFV(obj, STD_NET_INFO_LOCAL_PORT), sock->net.local_port);
60-
SET_INTEGER(OFV(obj, STD_NET_INFO_REMOTE_PORT), sock->net.remote_port);
121+
SET_OBJECT(ret, obj);
122+
Set_Tuple(OFV(obj, STD_NET_INFO_LOCAL_IP), (REBYTE *)&sock->net.local_ip, 4);
123+
Set_Tuple(OFV(obj, STD_NET_INFO_REMOTE_IP), (REBYTE *)&sock->net.remote_ip, 4);
124+
SET_INTEGER(OFV(obj, STD_NET_INFO_LOCAL_PORT), sock->net.local_port);
125+
SET_INTEGER(OFV(obj, STD_NET_INFO_REMOTE_PORT), sock->net.remote_port);
126+
}
127+
}
128+
129+
/***********************************************************************
130+
**
131+
*/ void Ret_Net_Modes(REBSER *port, REBVAL *ret)
132+
/*
133+
** Sets value with block of possible net mode names
134+
**
135+
***********************************************************************/
136+
{
137+
Set_Block(ret, Get_Object_Words(In_Object(port, STD_PORT_SCHEME, STD_SCHEME_INFO, 0)));
61138
}
62139

63140

@@ -264,7 +341,12 @@ enum Transport_Types {
264341
case A_QUERY:
265342
// Get specific information - the scheme's info object.
266343
// Special notation allows just getting part of the info.
267-
Ret_Query_Net(port, sock, D_RET);
344+
refs = Find_Refines(ds, ALL_QUERY_REFS);
345+
if ((refs & AM_QUERY_MODE) && IS_NONE(D_ARG(ARG_QUERY_FIELD))) {
346+
Ret_Net_Modes(port, D_RET);
347+
return R_RET;
348+
}
349+
Ret_Query_Net(port, sock, D_RET, D_ARG(ARG_QUERY_FIELD));
268350
break;
269351

270352
case A_OPENQ:

src/tests/test-udp-server.r3

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ stdout: system/ports/output
1414

1515
udp-server/awake: func [event /local port str] [
1616
port: event/port
17-
print ["[UDP Server] event:" event/type]
17+
print ["[UDP Server] event:" event/type "from ip:" query/mode port 'remote-ip ]
1818
switch event/type [
1919
read [
2020
str: to string! port/data

src/tests/units/port-test.r3

+19
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,25 @@ if all [
583583
===end-group===
584584

585585

586+
===start-group=== "TCP"
587+
--test-- "query net info"
588+
;@@ https://github.com/Oldes/Rebol-issues/issues/1712
589+
port: open tcp://8.8.8.8:80
590+
--assert [local-ip local-port remote-ip remote-port] = query/mode port none
591+
--assert 0.0.0.0 = query/mode port 'local-ip
592+
--assert 0 = query/mode port 'local-port
593+
--assert 0.0.0.0 = query/mode port 'remote-ip
594+
--assert 80 = query/mode port 'remote-port
595+
--assert all [
596+
port? wait [port 1] ;= wait for lookup, so remote-ip is resolved
597+
8.8.8.8 = query/mode port 'remote-ip
598+
[80 8.8.8.8] = query/mode port [remote-port remote-ip]
599+
[local-ip: 0.0.0.0 local-port: 0] = query/mode port [local-ip: local-port:]
600+
]
601+
try [close port]
602+
===end-group===
603+
604+
586605
===start-group=== "SYSTEM"
587606
--test-- "query system://"
588607
;@@ https://github.com/Oldes/Rebol-issues/issues/1373

0 commit comments

Comments
 (0)