Skip to content

Commit

Permalink
feat(socket): add support multicast
Browse files Browse the repository at this point in the history
```
sock:setoption('ip_add_membership', { multiaddr = '224.0.0.2', interface = '0.0.0.0' })
sock:setoption('ip_drop_membership', { multiaddr = '224.0.0.2', interface = '0.0.0.0' })

sock:setoption('ipv6_add_membership', { multiaddr = 'ff02::1', interface = 0 })
sock:setoption('ipv6_drop_membership', { multiaddr = 'ff02::1', interface = 0 })
```

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
  • Loading branch information
zhaojh329 committed Apr 11, 2024
1 parent dd5db47 commit a575d8e
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
24 changes: 24 additions & 0 deletions examples/network/multicast/recver.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env eco

local socket = require 'eco.socket'
local sys = require 'eco.sys'

sys.signal(sys.SIGINT, function()
print('\nGot SIGINT, now quit')
eco.unloop()
end)

local multicast_addr = '224.0.0.2'
local multicast_port = 8080

local sock, err = socket.listen_udp(nil, multicast_port)
if not sock then
error(err)
end

sock:setoption('ip_add_membership', { multiaddr = multicast_addr })

while true do
local data, peer = sock:recvfrom(1024)
print('recvfrom:', peer.ipaddr, peer.port, data)
end
31 changes: 31 additions & 0 deletions examples/network/multicast/sender.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env eco

local socket = require 'eco.socket'
local bufio = require 'eco.bufio'
local file = require 'eco.file'
local sys = require 'eco.sys'

sys.signal(sys.SIGINT, function()
print('\nGot SIGINT, now quit')
eco.unloop()
end)

local multicast_addr = '224.0.0.2'
local multicast_port = 8080

local sock, err = socket.udp()
if not sock then
error(err)
end

local b = bufio.new(0)

while true do
file.write(0, 'Please input: ')

local data = b:read('l')

if data ~= '' then
sock:sendto(data, multicast_addr, multicast_port)
end
end
50 changes: 50 additions & 0 deletions socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,52 @@ static int sockopt_set_bindtodevice(struct eco_socket *sock, lua_State *L, struc
return sockopt_set(sock, L, o, &ifr, sizeof(ifr));
}

static int sockopt_set_ip_membership(struct eco_socket *sock, lua_State *L, struct sock_opt *o)
{
struct ip_mreq mreq = {};
const char *multiaddr;

luaL_checktype(L, 3, LUA_TTABLE);

lua_getfield(L, 3, "multiaddr");

multiaddr = lua_tostring(L, -1);

if (!multiaddr || inet_pton(AF_INET, multiaddr, &mreq.imr_multiaddr) != 1)
luaL_argerror(L, 3, "multiaddr: not a valid IP address");

lua_getfield(L, 3, "interface");

if (lua_isstring(L, -1)) {
const char *interface = lua_tostring(L, -1);
if (inet_pton(AF_INET, interface, &mreq.imr_interface) != 1)
luaL_argerror(L, 3, "interface: not a valid IP address");
}

return sockopt_set(sock, L, o, &mreq, sizeof(mreq));
}

static int sockopt_set_ipv6_membership(struct eco_socket *sock, lua_State *L, struct sock_opt *o)
{
struct ipv6_mreq mreq;
const char *multiaddr;

luaL_checktype(L, 3, LUA_TTABLE);

lua_getfield(L, 3, "multiaddr");

multiaddr = lua_tostring(L, -1);

if (!multiaddr || inet_pton(AF_INET6, multiaddr, &mreq.ipv6mr_multiaddr) != 1)
luaL_argerror(L, 3, "multiaddr: not a valid IPv6 address");

lua_getfield(L, 3, "interface");

mreq.ipv6mr_interface = luaL_optinteger(L, -1, 0);

return sockopt_set(sock, L, o, &mreq, sizeof(mreq));
}

static struct sock_opt optsets[] = {
{"reuseaddr", SOL_SOCKET, SO_REUSEADDR, sockopt_set_boolean},
{"reuseport", SOL_SOCKET, SO_REUSEPORT, sockopt_set_boolean},
Expand All @@ -693,7 +739,11 @@ static struct sock_opt optsets[] = {
{"tcp_keepcnt", SOL_TCP, TCP_KEEPCNT, sockopt_set_int},
{"tcp_fastopen", SOL_TCP, TCP_FASTOPEN, sockopt_set_int},
{"tcp_nodelay", SOL_TCP, TCP_NODELAY, sockopt_set_boolean},
{"ip_add_membership", SOL_IP, IP_ADD_MEMBERSHIP, sockopt_set_ip_membership},
{"ip_drop_membership", SOL_IP, IP_DROP_MEMBERSHIP, sockopt_set_ip_membership},
{"ipv6_v6only", SOL_IPV6, IPV6_V6ONLY, sockopt_set_boolean},
{"ipv6_add_membership", SOL_IPV6, IPV6_ADD_MEMBERSHIP, sockopt_set_ipv6_membership},
{"ipv6_drop_membership", SOL_IPV6, IPV6_DROP_MEMBERSHIP, sockopt_set_ipv6_membership},
{"netlink_add_membership", SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, sockopt_set_int},
{"netlink_drop_membership", SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, sockopt_set_int},
{}
Expand Down

0 comments on commit a575d8e

Please sign in to comment.