Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 9 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ hss:
- 'scscf.ims.mnc001.mcc001.3gppnetwork.org'

roaming:
inbound:
# How to handle unknown IMSIs when inbound roaming. Valid options are:
# IMSI_UNKNOWN - Reject the request with the "IMSI_UNKNOWN" error code.
# ROAMING_NOT_ALLOWED - Reject the request with the "ROAMING_NOT_ALLOWED" error code.
# The latter is useful when operating a private network and public SIMs should not be allowed to connect.
# "Roaming not allowed" will cause the UE to not try again on this network.
# "Imsi unknown" may cause the UE to believe that its subscription is invalid.
# For private networks, "ROAMING_NOT_ALLOWED" is recommended. Otherwise, use "IMSI_UNKNOWN".

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about mentioning in CHANGELOG.md between ## [Unreleased] and ### Added that users may want to adjust their config to add reject_unknown_imsis_with: "ROAMING_NOT_ALLOWED" if they are running a private network?

reject_unknown_imsis_with: "ROAMING_NOT_ALLOWED"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be too much for this pull request, so feel free to reject the idea. But how about we check if this config option (and in the future: more config options) doesn't have an unexpected value set at the start of the main service of PyHSS and refuse to start up if that is the case? This would prevent users from accidentally making a typo in the config value and then possibly running with the wrong reject unknown setting.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this some more, it should be easy to add such a check in lib/pyhss_config.py.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've had the same thought the other day. I think I will just go ahead and add this to this PR as it should not be a big deal.

outbound:
# Whether or not to a subscriber to connect to an undefined network when outbound roaming.
allow_undefined_networks: True
Expand Down
1 change: 1 addition & 0 deletions docker/.env
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ HSS_DSR_EXTERNAL_IDENTIFIER=example
HSS_IGNORE_PURGE_UE_REQUEST=False
HSS_SCSCF_POOL=scscf.ims.mnc001.mcc001.3gppnetwork.org
HSS_ROAMING_ALLOW_UNDEFINED_NETWORKS=True
HSS_ROAMING_REJECT_UNKNOWN_IMSIS_WITH="ROAMING_NOT_ALLOWED"
HSS_SCTP_RTO_MAX=5000
HSS_SCTP_RTO_MIN=500
HSS_SCTP_RTO_INITIAL=1000
Expand Down
9 changes: 9 additions & 0 deletions docker/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,15 @@ hss:
- "${HSS_SCSCF_POOL:-scscf.ims.mnc001.mcc001.3gppnetwork.org}"

roaming:
inbound:
# How to handle unknown IMSIs when inbound roaming. Valid options are:
# IMSI_UNKNOWN - Reject the request with the "IMSI_UNKNOWN" error code.
# ROAMING_NOT_ALLOWED - Reject the request with the "ROAMING_NOT_ALLOWED" error code.
# The latter is useful when operating a private network and public SIMs should not be allowed to connect.
# "Roaming not allowed" will cause the UE to not try again on this network.
# "Imsi unknown" may cause the UE to believe that its subscription is invalid.
# For private networks, "ROAMING_NOT_ALLOWED" is recommended. Otherwise, use "IMSI_UNKNOWN".
reject_unknown_imsis_with: "${HSS_ROAMING_REJECT_UNKNOWN_IMSIS_WITH:-ROAMING_NOT_ALLOWED}"
outbound:
# Whether or not to a subscriber to connect to an undefined network when outbound roaming.
allow_undefined_networks: ${HSS_ROAMING_ALLOW_UNDEFINED_NETWORKS:-True}
Expand Down
11 changes: 9 additions & 2 deletions lib/diameter.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,13 @@ def __init__(

]

@staticmethod
def get_unknown_imsi_reject_cause() -> int:
if config['hss']['roaming']['inbound']['reject_unknown_imsis_with'] == 'ROAMING_NOT_ALLOWED':
return 5004 # DIAMETER_ERROR_ROAMING_NOT_ALLOWED
return 5001 # DIAMETER_ERROR_USER_UNKNOWN


#Generates rounding for calculating padding
def myround(self, n, base=4):
if(n > 0):
Expand Down Expand Up @@ -2244,7 +2251,7 @@ def Answer_16777251_318(self, packet_vars, avps):
usePrefix=True,
prefixHostname=self.hostname,
prefixServiceName='metric')
#Handle if the subscriber is not present in HSS return "DIAMETER_ERROR_USER_UNKNOWN"
#Handle if the subscriber is not present in HSS return the appropriate error
self.logTool.log(service='HSS', level='debug', message="Subscriber " + str(imsi) + " is unknown in database", redisClient=self.redisMessaging)
avp = ''
session_id = self.get_avp_data(avps, 263)[0] #Get Session-ID
Expand All @@ -2255,7 +2262,7 @@ def Answer_16777251_318(self, packet_vars, avps):
#Experimental Result AVP(Response Code for Failure)
avp_experimental_result = ''
avp_experimental_result += self.generate_vendor_avp(266, 40, 10415, '') #AVP Vendor ID
avp_experimental_result += self.generate_avp(298, 40, self.int_to_hex(5001, 4)) #AVP Experimental-Result-Code: DIAMETER_ERROR_USER_UNKNOWN (5001)
avp_experimental_result += self.generate_avp(298, 40, self.int_to_hex(self.get_unknown_imsi_reject_cause(), 4)) #AVP Experimental-Result-Code: DIAMETER_ERROR_USER_UNKNOWN (5001) or DIAMETER_ERROR_ROAMING_NOT_ALLOWED (5004)
avp += self.generate_avp(297, 40, avp_experimental_result) #AVP Experimental-Result(297)

avp += self.generate_avp(277, 40, "00000001") #Auth-Session-State
Expand Down
10 changes: 9 additions & 1 deletion lib/gsup/controller/air.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from logtool import LogTool
from utils import validate_imsi, InvalidIMSI

from pyhss_config import config

class AIRController(GsupController):
def __init__(self, logger: LogTool, database: Database):
Expand All @@ -27,6 +28,13 @@ def get_num_vectors_req(self, message: dict):
return max_num
return ret

@staticmethod
def _get_unknown_subscriber_reject_cause() -> GMMCause:
if config['hss']['roaming']['inbound']['reject_unknown_imsis_with'] == 'ROAMING_NOT_ALLOWED':
return GMMCause.ROAMING_NOTALLOWED
else:
return GMMCause.IMSI_UNKNOWN

async def handle_message(self, peer: IPAPeer, message: GsupMessage):
request_dict = message.to_dict()
imsi = GsupMessageUtil.get_first_ie_by_name(GsupMessageUtil.GSUP_MSG_IE_IMSI, request_dict)
Expand Down Expand Up @@ -79,7 +87,7 @@ async def handle_message(self, peer: IPAPeer, message: GsupMessage):
peer,
GsupMessageBuilder().with_msg_type(MsgType.SEND_AUTH_INFO_ERROR)
.with_ie('imsi', imsi)
.with_ie('cause', GMMCause.IMSI_UNKNOWN.value)
.with_ie('cause', self._get_unknown_subscriber_reject_cause().value)
.build(),
)
except Exception as e:
Expand Down
2 changes: 2 additions & 0 deletions tests/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ hss:
- 'scscf.ims.mnc001.mcc001.3gppnetwork.org'

roaming:
inbound:
reject_unknown_imsis_with: "ROAMING_NOT_ALLOWED"
outbound:
allow_undefined_networks: True

Expand Down