Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Service Overhaul #168

Merged
merged 44 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
eb7d970
Working Async socket read/write
davidkneipp Aug 18, 2023
6b354b5
Working diameterService and hssService
davidkneipp Aug 22, 2023
bfbbadc
Performance tuned diameterService.py, add GeoredService
davidkneipp Aug 23, 2023
b606aca
Add diameterAsync
davidkneipp Aug 24, 2023
c9f48b2
Add LogService
davidkneipp Aug 25, 2023
018e88a
Database partial refactor
davidkneipp Aug 28, 2023
5349db6
Add systemctl services
davidkneipp Aug 29, 2023
ebad1fe
Nearing completion, api refactored
davidkneipp Aug 30, 2023
f658418
Remove old.hss.py
davidkneipp Aug 30, 2023
3a6e12d
Progress Freeze, update config.yaml, functional
davidkneipp Aug 31, 2023
a9d7ccd
Update requirements.txt
davidkneipp Aug 31, 2023
276c94d
Fix Redis hang, update CLR
davidkneipp Sep 11, 2023
011ad94
Update diameter.py
davidkneipp Sep 13, 2023
f0c811f
Add geored peers and webhooks to api
davidkneipp Sep 14, 2023
ac67d0e
Add metrics.py
davidkneipp Sep 19, 2023
c1996f3
Memory leak fix
davidkneipp Sep 21, 2023
db6f6e1
Fix for sqn resync
davidkneipp Sep 21, 2023
e309932
Fix for Tac Database handling
davidkneipp Sep 23, 2023
3ea11b4
Asymmetric geored, CLR fix, logic fixes
davidkneipp Sep 24, 2023
eb603bf
Update README.md
davidkneipp Sep 24, 2023
b354a61
Fix method typo
davidkneipp Sep 24, 2023
5179e0d
Basic Rx support
davidkneipp Sep 26, 2023
5c12ee1
Fix in CCA for apn being in plmn-based string
davidkneipp Sep 26, 2023
d03d26c
Improve /deregister, fix /oam/diameter_peers, add dra peerType
davidkneipp Sep 27, 2023
4c8022c
Remove theading import
davidkneipp Sep 27, 2023
d776dc9
Initial changelog
davidkneipp Sep 27, 2023
7d15449
Fix APC and APV AVPs
davidkneipp Sep 28, 2023
7420ecc
Fix for empty geored / webhook peers when defined
davidkneipp Sep 28, 2023
32d3252
Fix webhook always sending post
davidkneipp Sep 29, 2023
d65cd8d
Add configurable redis connection in config.yaml
davidkneipp Sep 29, 2023
b42a9ea
Add PCSCF state management, basic database upgrade support
davidkneipp Sep 29, 2023
c0a7c43
Working Rx Call, dedicated bearer setup
davidkneipp Sep 29, 2023
dca0038
Geored fixes
davidkneipp Sep 30, 2023
b3a7cb1
Rx Call setup awaiting RAA per correct flow
davidkneipp Oct 2, 2023
5260314
Successful Rx Call, with dedicated bearer setup and teardown
davidkneipp Oct 3, 2023
7b355b5
Update geored schema
davidkneipp Oct 3, 2023
612d9fa
All CPU overutilzation fixed, add benchmarking to config.yaml, minor …
davidkneipp Oct 4, 2023
7c7af2e
Fixes after queue restructure
davidkneipp Oct 4, 2023
cca7fef
Allow null on geored patch
davidkneipp Oct 4, 2023
09f461a
Remove forced string typing in database geored
davidkneipp Oct 4, 2023
946b20e
Further performance improvements, worker pool
davidkneipp Oct 6, 2023
0925383
Disable webhooks by default in config.yaml
davidkneipp Oct 6, 2023
06d0d8e
Update default ip in webhooks
davidkneipp Oct 9, 2023
553b68b
Fix merge conflicts
davidkneipp Oct 9, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Changelog

All notable changes to PyHSS are documented in this file, beginning from [Service Overhaul #168](https://github.com/nickvsnetworking/pyhss/pull/168).

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0] - 2023-09-27

### Added

- Systemd service files for PyHSS services
- /oam/diameter_peers endpoint
- /oam/deregister/{imsi} endpoint
- /geored/peers endpoint
- /geored/webhooks endpoint
- Dependency on Redis 7 for inter-service messaging
- Significant performance improvements under load
- Basic Rx support for RAA, AAA, ASA and STA
- Rx MO call flow support (AAR -> RAR -> RAA -> AAA)
- Dedicated bearer setup and teardown on Rx call
- Asymmetric geored support
- Configurable redis connection (Unix socket or TCP)
- Basic database upgrade support in tools/databaseUpgrade
- PCSCF state storage in ims_subscriber
- (Experimental) Working horizontal scalability

### Changed

- Split logical functions of PyHSS into 6 service processes
- Logtool no longer handles metric processing
- Updated config.yaml
- Gx CCR-T now flushes PGW / IMS data, depending on Called-Station-Id
- Benchmarked capability of at least ~500 diameter requests per second with a response time of under 2 seconds on a local network.

### Fixed

- Memory leaking in diameter.py
- Gx CCA now supports apn inside a plmn based uri
- AVP_Preemption_Capability and AVP_Preemption_Vulnerability now presents correctly in all diameter messages
- Crash when webhook or geored endpoints enabled and no peers defined
- CPU overutilization on all services

### Removed

- Multithreading in all services, except for metricService

[1.0.0]: https://github.com/nickvsnetworking/pyhss/releases/tag/v1.0.0
35 changes: 24 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,28 @@ Basic configuration is set in the ``config.yaml`` file,

You will need to set the IP address to bind to (IPv4 or IPv6), the Diameter hostname, realm, your PLMN and transport type to use (SCTP or TCP).

Once the configuration is done you can run the HSS by running ``hss.py`` and the server will run using whichever transport (TCP/SCTP) you have selected.
The diameter service runs in a trusting mode allowing Diameter connections from any other Diameter hosts.

The service runs in a trusting mode allowing Diameter connections from any other Diameter hosts.
To perform as a functioning HSS, the following services must be run as a minimum:
- diameterService.py
- hssService.py

## Structure
If you're provisioning the HSS for the first time, you'll also want to run:
- apiService.py

The file *hss.py* runs a threaded Sockets based listener (SCTP or TCP) to receive Diameter requests, process them and send back Diameter responses.
The rest of the services aren't strictly necessary, however your own configuration will dictate whether or not they are required.

Most of the heavy lifting in this is managed by the Diameter class, in ``diameter.py``. This:
## Structure

* Decodes incoming packets (Requests)(Returns AVPs as an array, called *avp*, and a Dict containing the packet variables (called *packet_vars*)
* Generates responses (Answer messages) to Requests (when provided with the AVP and packet_vars of the original Request)
* Generates Requests to send to other peers
PyHSS uses a queued microservices model. Each service performs a specific set of tasks, and uses redis messages to communicate with other services.

The following services make up PyHSS:
- diameterService.py: Handles receiving and sending of diameter messages, and diameter client connection state.
- hssService.py: Provides decoding and encoding of diameter requests and responses, as well as logic to perform as a HSS.
- apiService.py: Provides the API, to allow management of PyHSS.
- georedService.py: Sends georaphic redundancy messages to geored peers when defined. Also handles webhook messages.
- logService.py: Handles logging for all services.
- metricService.py: Exposes prometheus metrics from other services.

## Subscriber Information Storage

Expand All @@ -71,12 +79,17 @@ Dependencies can be installed using Pip3:
pip3 install -r requirements.txt
```

Then after setting up the config, you can fire up the HSS itself by running:
PyHSS also requires [Redis 7.0.0](https://redis.io/docs/getting-started/installation/install-redis-on-linux/) or above.

Then after setting up the config, you can fire up the necessary PyHSS services by running:
```shell
python3 hss.py
python3 diameterService.py
python3 hssService.py
python3 apiService.py
```

All going well you'll have a functioning HSS at this point.
All going well you'll have a functioning HSS at this point. For production use, systemd scripts are located in `./systemd`
PyHSS API uses Flask, and can be configured with your favourite WSGI server.

To get everything more production ready checkout [Monit with PyHSS](docs/monit.md) for more info.

Expand Down
49 changes: 29 additions & 20 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ hss:
#IMSI of Test Subscriber for Unit Checks (Optional)
test_sub_imsi: '001021234567890'

#Device Watchdog Request Interval (In Seconds - If set to 0 disabled)
device_watchdog_request_interval: 0

#Async Queue Check Interval (In Seconds - If set to 0 disabled)
async_check_interval: 0

#The maximum time to wait, in seconds, before disconnecting a client when no data is received.
client_socket_timeout: 120

#The maximum amount of times a failed diameter response/query should be resent before considering the peer offline and terminating their connection
diameter_max_retries: 1
#The maximum time to wait, in seconds, before disconnecting a client when no data is received.
client_socket_timeout: 300

#The maximum time to wait, in seconds, before discarding a diameter request.
diameter_request_timeout: 3

#The amount of time, in seconds, before purging a disconnected client from the Active Diameter Peers key in redis.
active_diameter_peers_timeout: 10

#Prevent updates from being performed without a valid 'Provisioning-Key' in the header
lock_provisioning: False
Expand Down Expand Up @@ -68,22 +68,24 @@ hss:
api:
page_size: 200

external:
external_webhook_notification_enabled: False
external_webhook_notification_url: https://api.example.com/webhook
benchmarking:
# Whether to enable benchmark logging
enabled: True
# How often to report, in seconds. Not all benchmarking supports interval reporting.
reporting_interval: 3600

eir:
imsi_imei_logging: True #Store current IMEI / IMSI pair in backend
sim_swap_notify_webhook: http://localhost:5000/webhooks/sim_swap_notify/
no_match_response: 2 #Greylist
tac_database_csv: '/etc/pyhss/tac_database_Nov2022.csv'

logging:
level: DEBUG
level: INFO
logfiles:
hss_logging_file: log/hss.log
diameter_logging_file: log/diameter.log
database_logging_file: log/db.log
hss_logging_file: /var/log/pyhss_hss.log
diameter_logging_file: /var/log/pyhss_diameter.log
geored_logging_file: /var/log/pyhss_geored.log
metric_logging_file: /var/log/pyhss_metrics.log
log_to_terminal: True
sqlalchemy_sql_echo: True
sqlalchemy_pool_recycle: 15
Expand All @@ -98,18 +100,25 @@ database:
password: password
database: hss2

## External Webhook Notifications
webhooks:
enabled: False
endpoints:
- http://127.0.0.1:8181

## Geographic Redundancy Parameters
geored:
enabled: False
sync_actions: ['HSS', 'IMS', 'PCRF', 'EIR'] #What event actions should be synced
sync_endpoints: #List of PyHSS API Endpoints to update
endpoints: #List of PyHSS API Endpoints to update
- 'http://hss01.mnc001.mcc001.3gppnetwork.org:8080'
- 'http://hss02.mnc001.mcc001.3gppnetwork.org:8080'

## Stats Parameters
#Redis is required to run PyHSS. A locally running instance is recommended for production.
redis:
enabled: False
clear_stats_on_boot: True
# Whether to use a UNIX socket instead of a tcp connection to redis. Host and port is ignored if useUnixSocket is True.
useUnixSocket: False
unixSocketPath: '/var/run/redis/redis-server.sock'
host: localhost
port: 6379

Expand Down
Loading