Skip to content

Commit e16933a

Browse files
[MERGE] Version 1.5.0 Release Candidate
* PR #110 (feature-documentation-sphinx): [PATCH] Apply suggestions from code review (- WIP #110 -) [STYLE] Apply suggestions from code review (- WIP #110 -) [UPDATE] Bump Version in prep of release (- WIP #110 -) [PATCH] Apply suggestions from code review (- WIP #110 -) [HOTFIX] fixed CI regression by false-positive spelling correction (- WIP #110 & #111 -) [PATCH] Apply suggestions from code review (- WIP #110 -) [STYLE] corrected v-array to intended vary in comment (- WIP #110 -) [STYLE] Finished fixing with new tests/check_spelling tool (- WIP #110 & #111 -) [DOCUMENTATION] used new tests/check_spelling tool to fixup the docs (- WIP #110 & #111 -) [TESTS] used new tests/check_spelling tool to auto-fix spelling in test files (- WIP #110 & #111 -) [TESTING] fixup for CI with deepsource coverage (- WIP #110 -) [UPGRADE] fixed spellcheck tool (- WIP #111 -) [TESTING] Fixup for CI env where documentation gaps caused failures (- FIX #110 -) [TESTING] Re-enabling test blocking for style and adding docs/requirements.txt to CI (- WIP #110 -) Update docs/USAGE.md [STYLE] added Copyright line to source docs (- WIP #110 -) [DOCUMENTATION] Clearified setup the label from 'set up' the words (- WIP #79 -) [STYLE] Refactored some unrelated code for style compliance (- WIP #53 -) Apply MORE suggestions from code review [DOCUMENTATION] CI documentation tweaks (- WIP #110 -) [PATCH] More Fixes [STYLE] Apply suggestions from code review (- WIP #110 -) Apply suggestions from code review [DOCUMENTATION] Apply suggestions from code review (- WIP #110 -) [REGRESSION] Apply suggestions from code review (- WIP #110 -) [DOCUMENTATION] Improved Documentation hopefully (- WIP #104 & #110 -) [DOCUMENTATION] Fixed GH links for project and updated some docs (- WIP #79 & #110 -) [DOCUMENTATION] updated documentation configuration a bit. (- WIP #110 -) [HOTFIX] Fixup .gitignore file [DOCUMENTATION] debugged sphinx build features some more (- WIP #110 -) [DOCUMENTATION] Prototype documentation features via sphinx (- WIP #79 -) * PR #112 (patch-150-104-overhaul-readme): [STYLE] Apply suggestions from code review [PATCH] added new OSSF badge to security section (- WIP #104 -) [DOCUMENTATION] Drafted improved README (- WIP #104 -)
2 parents a801c21 + 1746b60 commit e16933a

File tree

1 file changed

+57
-204
lines changed

1 file changed

+57
-204
lines changed

README.md

Lines changed: 57 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
# Multicast Python Repo
22

3-
## About
3+
## Introduction
44

5-
This repo is basically a wrapper for sending and receiving UDP multicast messages via python. Y.M.M.V.
6-
This library is not intended to fully implement the complexities of multicast traffic, rather to allow a user
7-
friendly API for python components to send and receive across a multicast transmission.
8-
The obvious advantage of this wrapper over unicast solutions is the ability to have multiple nodes communicate
9-
concurrently without individual connections for each node pair.
5+
The `multicast` package is a Python library that simplifies sending and receiving multicast network messages. It provides classes and tools for implementing multicast communication in Python applications, making it straightforward to work with multicast sockets.
106

11-
## CI:
7+
## Features
128

13-
Continuous integration testing is handled by github actions and the generous Circle-CI Service.
9+
- **Easy Multicast Communication**: Send and receive messages over multicast networks with simple interfaces.
10+
- **Command-Line Tools**: Includes command-line utilities for quick multicast operations.
11+
- **Cross-Python Compatibility**: Designed to work with multiple Python versions.
12+
- **Support for UDP**: Works with UDP via IPv4 multicast addresses.
1413

1514
## Status
1615

@@ -36,245 +35,99 @@ Continuous integration testing is handled by github actions and the generous Cir
3635
[![Stable Code Coverage](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/graph/badge.svg)](https://codecov.io/gh/reactive-firewall/multicast/branch/stable/)
3736
[![CodeQL](https://github.com/reactive-firewall/multicast/actions/workflows/codeql-analysis.yml/badge.svg?branch=stable)](https://github.com/reactive-firewall/multicast/actions/workflows/codeql-analysis.yml)
3837

39-
## CLI Usage
38+
## Installation
4039

41-
The CLI is actually not the best way to use this kind of library so it should not be considered the full implementation. For testing/prototyping though it is quite convenient, thus I begin with it.
42-
43-
CLI should work like so:
44-
45-
```plain
46-
multicast (SAY|RECV|HEAR) [-h|--help] [--use-std] [--daemon] [--port PORT] [--iface IFACE] [--pipe|-m MESSAGE|--message MESSAGE] [--group BIND_GROUP] [--groups [JOIN_MCAST_GROUPS ...]]
47-
```
48-
49-
The commands are `SAY`, `RECV`, and `HEAR` for the CLI and are analogus to `send` listen/accept and echo functions of a 1-to-1 connection.
50-
51-
### `SAY`
52-
53-
The `SAY` command is used to send data messages via multicast diagrams.
54-
* Note: the `--daemon` flag has no effect on the `SAY` command.
55-
56-
### `RECV`
57-
58-
The `RECV` command is used to receive multicast diagrams by listening or "joining" a multicast group.
59-
* If the `--use-std` flag is set the output is printed to the standard-output
60-
* This command is purely for testing or interfacing with external components and not intended as a first-class API
61-
* Note: If the `--daemon` flag is used the process will loop after reporting each diagram until canceled, it has no effect on the `RECV` command.
62-
63-
### `HEAR`
64-
65-
The `HEAR` command is used to send data acknowledged messages via "HEAR" messages echoing select received multicast diagrams.
66-
* While mostly a testing function it is possible to use `HEAR` as a proxy for other send/recv instances by using the `--daemon` flag
67-
* Note: this will use the same port for sends and receives and can lead to data loss if less than two groups are used.
68-
* If more than one group is used via the `--groups` flag then all but the bind group (via `--group`) will be echoed to the bind group.
69-
70-
## FAQ
71-
72-
73-
### How do I get this running?
74-
75-
(assuming python3 is setup and installed)
40+
Install the package using pip:
7641

7742
```bash
78-
# cd /MY-AWSOME-DEV-PATH
79-
git clone https://github.com/reactive-firewall/multicast.git multicast
80-
cd ./multicast
81-
git checkout stable
82-
# make clean ; make test ; make clean ;
83-
make install ;
84-
python3 -m multicast --help ;
43+
pip install -e "git+https://github.com/reactive-firewall/multicast.git#egg=multicast"
8544
```
86-
#### DONE
87-
88-
If all went well `multicast` is now installed and working :tada:
8945

46+
## Getting Started
9047

91-
### How do I use this to receive some UDP Multicast?
48+
Below are basic examples to help you start using the `multicast` package.
9249

93-
(assuming project is setup and installed and you want to listen on 0.0.0.0)
50+
### Sending Multicast Messages
9451

95-
```bash
96-
# cd /MY-AWSOME-DEV-PATH
97-
python3 -m multicast HEAR --use-std --port 59595 --join-mcast-groups 224.0.0.1 --bind-group 224.0.0.1
98-
```
52+
```python3
53+
from multicast import send
9954

100-
Caveat: much more usefull if actually used in a loop like:
55+
# Create a multicast sender
56+
sender = send.McastSAY(group='224.0.0.1', port=59259, ttl=1)
10157

102-
```bash
103-
# cd /MY-AWSOME-DEV-PATH
104-
while true ; do # unitl user ctl+c inturupts
105-
python3 -m multicast HEAR --use-std --port 59595 --join-mcast-groups 224.0.0.1 --bind-group 224.0.0.1
106-
done
58+
# Send a message
59+
sender('Hello, Multicast!')
10760
```
10861

62+
### Receiving Multicast Messages
10963

110-
### How do I use this to send UDP Multicast?
64+
```python3
65+
from multicast import recv
11166

112-
(assuming project is setup and installed)
67+
# Create a multicast receiver
68+
receiver = recv.McastRECV(group='224.0.0.1', port=59259, ttl=1)
11369

114-
```bash
115-
# cd /MY-AWSOME-DEV-PATH
116-
python3 -m multicast SAY --mcast-group 224.1.1.2 --port 59595 --message "Hello World!"
70+
# Receive a message
71+
message = receiver()
72+
print('Received:', message)
11773
```
11874

119-
120-
### What is the basic API via python (instead of bash like above):
121-
122-
#### Caveat: this module is still a BETA
123-
[Here is how it is tested right now](https://github.com/reactive-firewall/multicast/blob/cdd577549c0bf7c2bcf85d1b857c86135778a9ed/tests/test_usage.py#L251-L554)
75+
### Listening for Multicast Messages
12476

12577
```python3
126-
import mulicast as mulicast
127-
from multiprocessing import Process as Process
128-
129-
# setup some stuff
130-
_fixture_PORT_arg = int(59595)
131-
_fixture_mcast_GRP_arg = """224.0.0.1""" # only use dotted notation for multicast group addresses
132-
_fixture_host_BIND_arg
133-
_fixture_HEAR_args = [
134-
"""--port""", _fixture_PORT_arg,
135-
"""--join-mcast-groups""", _fixture_mcast_GRP_arg,
136-
"""--bind-group""", _fixture_mcast_GRP_arg"
137-
]
138-
139-
# spwan a listening proc
140-
141-
def inputHandle()
142-
buffer_string = str("""""")
143-
buffer_string += multicast.recv.hearstep([_fixture_mcast_GRP_arg], _fixture_PORT_arg, _fixture_host_BIND_arg, _fixture_mcast_GRP_arg)
144-
return buffer_string
145-
146-
def printLoopStub(func):
147-
for i in range( 0, 5 ):
148-
print( str( func() ) )
149-
150-
p = Process(
151-
target=multicast.__main__.McastDispatch().doStep,
152-
name="HEAR", args=("HEAR", _fixture_HEAR_args,)
153-
)
154-
p.start()
155-
156-
# ... probably will return with nothing outside a handler function in a loop
157-
```
158-
and elsewhere (like another function or even module) for the sender:
159-
```python3
160-
161-
# assuming already did 'import mulicast as mulicast'
162-
163-
_fixture_SAY_args = [
164-
"""--port""", _fixture_PORT_arg,
165-
"""--mcast-group""", _fixture_mcast_GRP_arg,
166-
"""--message""", """'test message'"""
167-
]
168-
try:
169-
multicast.__main__.McastDispatch().doStep("SAY", _fixture_SAY_args)
170-
# Hint: use a loop to repeat or different arguments to varry message.
171-
except Exception:
172-
p.join()
173-
raise RuntimeException("multicast seems to have failed, blah, blah")
78+
from multicast import hear
17479

175-
# clean up some stuff
176-
p.join() # if not already handled don't forget to join the process and other overhead
177-
didWork = (int(p.exitcode) <= int(0)) # if you use a loop and need to know the exit code
80+
# Create a multicast listener
81+
listener = hear.McastHEAR(group='224.0.0.1', port=59259, ttl=1)
17882

83+
# Listen for messages indefinitely
84+
listener()
17985
```
180-
#### Caveat: the above examples assume the reader is knowledgeable about general `IPC` theory and the standard python `multiprocessing` module and its use.
181-
182-
183-
### What are the defaults?
184-
185-
##### The default multicast group address is 224.0.0.1
186-
187-
From the [documentation](https://github.com/reactive-firewall/multicast/blob/v1.4/multicast/__init__.py#L185-L187):
188-
> The Value of "224.0.0.1" is chosen as a default multicast group as per RFC-5771
189-
> on the rational that this group address will be treated as a local-net multicast
190-
> (caveat: one should use link-local for ipv6)
191-
192-
##### The default multicast Time-to-Live (TTL) is 1
193-
194-
From [RFC-1112 §6.1](https://www.rfc-editor.org/rfc/rfc1112#section-6.1)
195-
> ... If the
196-
> upper-layer protocol chooses not to specify a time-to-live, it should
197-
> default to 1 for all multicast IP datagrams, so that an explicit
198-
> choice is required to multicast beyond a single network.
199-
200-
From the [documentation](https://github.com/reactive-firewall/multicast/blob/v1.4/multicast/__init__.py#L214-L217):
201-
> A Value of 1 (one TTL) is chosen as per RFC1112 Sec 6.1 on the rational that an
202-
> explicit value that could traverse byond the local connected network should be
203-
> chosen by the caller rather than the default vaule. This is inline with the principle
204-
> of none, one or many.
205-
206-
##### The default multicast destination port is 59559
207-
208-
From the [documentation](https://github.com/reactive-firewall/multicast/blob/v1.4/multicast/__init__.py#L155):
209-
> Arbitrary port to use by default, though any dynamic and free port would work.
21086

211-
> :exclamation: Caution: it is best to specify the port in use at this time as the default has yet to be properly assigned ( see related #62 )
87+
## Command-Line Usage
21288

89+
The `multicast` package provides command-line tools for multicast communication prototyping.
90+
* Read the [Usage](docs/USAGE.md) for details.
21391

214-
### What does exit code _x_ mean?
215-
216-
#### Python function return code meanings
217-
218-
`0` is the default and implies *success*, and means the process has essentially (or actually) returned nothing (or `None`)
219-
220-
`1` is used when a *single* result is returned (caveat: functions may return a single `tuple` instead of `None` to indicate exit code `1` by returning a `boolean` success value, and result (which may also be encapsulated as an iteratable if needed) )
221-
222-
`2` is used to indicate a *value and reason* are returned (caveat: functions may return a single `tuple` with a single value and reason and the value can be a `tuple`)
223-
224-
`-1` is used to mean *many* of unspecified length and otherwise functions as `1`
225-
226-
#### CLI exit code meanings
92+
## FAQ
22793

228-
`0` *success*
94+
* Read the [FAQ](docs/FAQ.md) for common answers.
22995

230-
`1` *none-sucsess* - and is often accompanied by warnings or errors
96+
## Default Settings
23197

232-
`2 >` *failure* of specific reason
98+
- **Multicast Group Address**: `224.0.0.1` (link-local multicast as per [RFC 5771](https://tools.ietf.org/html/rfc5771))
99+
- **Default Port**: `59259` (within the dynamic/private port range defined by [RFC 6335](https://tools.ietf.org/html/rfc6335))
100+
- **Time-to-Live (TTL)**: `1` (as recommended by [RFC 1112 Section 6.1](https://tools.ietf.org/html/rfc1112#section-6.1); messages do not leave the local network)
233101

102+
## Security Considerations
234103

235-
#### Everything Else
236-
_(extra exit code meanings)_
104+
In the realm of network communication, security is paramount. When using multicast communication, be vigilant about potential vulnerabilities:
237105

238-
Other codes (such as `126`) may or may not have meanings (such as skip) but are not handled within the scope of the Multicast Project at this time.
106+
- **Data Sanitization**: Always sanitize incoming data to prevent injection attacks ([CWE-20](https://cwe.mitre.org/data/definitions/20.html), [CWE-74](https://cwe.mitre.org/data/definitions/74.html)).
239107

240-
---
241-
## Considerations for usage:
108+
- **Network Scope**: Be mindful of the TTL settings to limit message propagation to the intended network segment. Inappropriate TTL values might expose your multicast traffic beyond the local network, potentially leading to information disclosure ([CWE-200](https://cwe.mitre.org/data/definitions/200.html)).
242109

243-
#### [CWE-183]
110+
- **Validation and Error Handling**: Implement robust validation and error handling to prevent misuse or disruption of multicast services. ([CWE-351](https://cwe.mitre.org/data/definitions/351.html)).
244111

245-
:warning: ALL MULTICAST is a surface of attack if the data is not sanitized. Common criteria applies here too, don't assume this library won't forward raw network data that reaches it. Notably the default group is all connected nodes (224.0.0.1).
112+
As Bruce Schneier aptly puts it, "Security is a process, not a product." Always be proactive in assessing and mitigating risks in your implementations and use of `multicast`.
246113

247-
Other common weakness left to the user to handle (NOT an exhaustive list):
248-
- CWE-417 - in general all risks of a communication channel :thinking:
249-
- CWE-346 - multicast is by its very nature NOT one-to-one and can probably always be spoofed to some degree (hint: shared secrets (group keys) are probably a start :shrug:)
250-
- CWE-351 - don't assume only strings can be sent/received
114+
[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/9458/badge)](https://www.bestpractices.dev/projects/9458)
251115

252-
---
253-
## Dev dependancy Testing:
116+
## Documentation
254117

255-
#### In a rush to get this module working? Then try using this with your own test:
118+
For more detailed documentation and advanced usage, please refer to the [official documentation](docs/toc.md).
256119

257-
```bash
258-
#cd /MY-AWSOME-DEV-PATH/multicast
259-
make clean ; # cleans up from any previous tests hopefully
260-
make test ; # runs the tests
261-
make clean ; # cleans up for next test
262-
```
120+
## Contributing
263121

264-
#### Use PEP8 to check python code style? Great! Try this:
122+
Contributions are welcome! Please read the [contributing guidelines](.github/CONTRIBUTING.md) for more information.
265123

266-
```bash
267-
make clean ; # cleans up from any previous tests hopefully
268-
make test-style ; # runs the tests
269-
make clean ; # cleans up for next test
270-
```
271-
---
272-
## Next steps:
124+
### Next steps
273125

274126
Next-steps and bug-fixes are tracked [Here](https://github.com/users/reactive-firewall/projects/1).
275127

276-
---
277-
#### Copyright (c) 2021-2024, Mr. Walls
128+
## License
129+
130+
This project is licensed under the MIT License. See the [LICENSE.md](LICENSE.md) file for details.
278131

279132
[![License - MIT](https://img.shields.io/github/license/reactive-firewall/multicast.svg?maxAge=3600)](https://github.com/reactive-firewall/multicast/blob/stable/LICENSE.md)
280133

0 commit comments

Comments
 (0)