aboutsummaryrefslogtreecommitdiffstats
AgeCommit message (Collapse)AuthorFilesLines
2020-05-01release 1.2.0-fw.1fairwaves/1.2.0-fw.1fairwaves/productionKirill Zakharenko1-0/+6
2020-04-30auc3g: officially wrap IND around IND_bitlen spaceNeels Hofmeyr1-8/+9
To determine distinct IND pools for each connected VLR, we need to pick ever increasing values for any new peer showing up. Each subscriber's individual IND_bitlen is then required to modulo the least significant N of bits that fit in its IND_bitlen to effectively round-robin in the available IND pool space. So far we did that but issued a warning message. This is actually exactly what we want and it doesn't need to be treated like it weren't so. Change-Id: I716d8a8a249235c8093d7a6a78b3535d893d867e
2020-04-30vty: show subscriber: show lu d,h,m,s ago, not just secondsNeels Hofmeyr1-2/+14
Change-Id: I0fe34e0f065160ef959b2b7b4dd040f3f2985f43
2020-04-30vty: show subscriber: change format of 'last LU seen'Neels Hofmeyr1-11/+7
So far, the time string format comes from ctime_r, and we manually add "UTC" to it. The ctime_r format is wildly chaotic IMHO, mixing weekday, day-of-month and hour and year in very unsorted ways. Adding "UTC" to it is non-standard. Instead use an ISO-8601 standardized time string via strftime(). Change-Id: I6731968f05050399f4dd43b241290186e0c59e1a
2020-04-30drop error log for when a subscriber does not existNeels Hofmeyr2-30/+4
Checking for existence of a subscriber and seeing that there is none is not inherently an error. However, osmo-hlr currently logs on all occasions: DAUC ERROR Cannot read subscriber from db: MSISDN='1001': No such subscriber This spams the ERROR log level. Particularly when a D-GSM setup does subscriber existence checks for every incoming mslookup request, that potentially creates constant ERROR logging. The "No such subscriber" part comes from db_sel(), which might also return an sqlite3_errmsg(). We still want those sqlite3_errmsg()es in the ERROR log. Hence print an ERROR log only if db_sel() returns an rc != -ENOENT. Change-Id: I5044e9b4519b948edc4e451cef0f7830d315619b
2020-04-30adoc: add D-GSM chapter to osmohlr-usermanualNeels Hofmeyr3-0/+515
Change-Id: I392b5523870c2ef3267179160028d26f3f761b77
2020-04-30hlr_vty_subscr: prettier output for last LU seenOliver Smith1-2/+7
Extend the "last LU seen on ..." line with the amount of seconds that passed since now, or "(invalid timestamp)". Patch split from Id7fc50567211a0870ac0524f6dee94d4513781ba, because it depends on timestamp_age which was just added in Ife4a61d71926d08f310a1aeed9d9f1974f64178b. Change-Id: I24f9e86c1aa0b1576290094e024562f41b988f37
2020-04-30gsup_server: send routing error back to the correct peerNeels Hofmeyr1-3/+14
If a peer attempts to add a route to an ipa-name that we already have in the routing system, don't send the routing error to the peer that already has the name, but to the peer that attempts to re-use it and would cause the collision. This is fixing a situation where for example a locally attached MSC has name 'MSC-1', and a remote site is proxying GSUP here for a remote MSC that also has the name 'MSC-1'. Send the routing error back to the proxy, not local 'MSC-1'. Change-Id: Icafaedc11b5925149d338bdcb987ae985a7323d6
2020-04-30D-GSM 3/n: implement roaming by mslookup in osmo-hlrNeels Hofmeyr21-9/+2006
Add mslookup client to find remote home HLRs of unknown IMSIs, and proxy/forward GSUP for those to the right remote HLR instances. Add remote_hlr.c to manage one GSUP client per remote HLR GSUP address. Add proxy.c to keep state about remotely handled IMSIs (remote GSUP address, MSISDN, and probably more in future patches). The mslookup_server that determines whether a given MSISDN is attached locally now also needs to look in the proxy record: it is always the osmo-hlr immediately peering for the MSC that should respond to mslookup service address queries like SIP and SMPP. (Only gsup.hlr service is always answered by the home HLR.) Add dgsm.c to set up an mdns mslookup client, ask for IMSI homes, and to decide which GSUP is handled locally and which needs to go to a remote HLR. Add full VTY config and VTY tests. For a detailed overview of the D-GSM and mslookup related files, please see the elaborate comment at the top of mslookup.c (already added in an earlier patch). Change-Id: I2fe453553c90e6ee527ed13a13089900efd488aa
2020-04-30D-GSM 2/n: implement mDNS method of mslookup serverNeels Hofmeyr11-1/+605
Implement the mslookup server's mDNS responder, to actually service remote mslookup requests: - VTY mslookup/server config with service names, - the mslookup_mdns_server listening for mslookup requests, For a detailed overview of the D-GSM and mslookup related files, please see the elaborate comment at the top of mslookup.c (already added in an earlier patch). Change-Id: I5cae6459090588b4dd292be90a5e8903432669d2
2020-04-30D-GSM 1/n: add mslookup server in osmo-hlrNeels Hofmeyr8-0/+537
Implement the mslookup server to service remote mslookup requests. This patch merely adds the logic to answer incoming mslookup requests, an actual method to receive requests (mDNS) follows in a subsequent patch. - API to configure service names and addresses for the local site (per MSC). - determine whether a subscriber is on a local MSC (checking the local proxy will be added in subsequent patch that adds proxy capability). - VTY config follows in a subsequent patch. For a detailed overview of the D-GSM and mslookup related files, please see the elaborate comment at the top of mslookup.c (already added in an earlier patch). Change-Id: Ife4a61d71926d08f310a1aeed9d9f1974f64178b
2020-04-30test_nodes.vty: remove cruftNeels Hofmeyr1-64/+1
This stuff is not testing osmo-hlr specific nodes, remove. Change-Id: Ia11a209778b78ab02424e2abf3f9004fe97cf570
2020-04-30enlarge the GSUP message headroomNeels Hofmeyr1-1/+1
Make room for (more) arbitrary IPA headers, like longer IPA names as configured by the user. Change-Id: I7d86f2dadcae29fe1550ea2c9773394ab31a837b
2020-04-30db v5: prep for D-GSM: add vlr_via_proxy and sgsn_via_proxyNeels Hofmeyr5-14/+75
D-GSM will store in the HLR DB whether a locally connected MSC has attached the subscriber (last_lu_seen[_ps]), or whether the attach happened via a GSUP proxy from a different site. Add columns for this separately in this patch. Change-Id: I98c7b3870559ede84adf56e4bf111f53c7487745
2020-04-30gsup client: add up_down_cb(), add osmo_gsup_client_create3()Neels Hofmeyr2-20/+74
For the GSUP clients in upcoming D-GSM enabled osmo-hlr, it will be necessary to trigger an event as soon as a GSUP client connection becomes ready for communication. Add the osmo_gsup_client->up_down_cb. Add osmo_gsup_client_create3() to pass the up_down_cb in the arguments. Also add a cb data argument to populate the already existing osmo_gsup_client->data item directly from osmo_gsup_client_create3(). We need the callbacks and data pointer in the osmo_gsup_client_create() function right before startup, because this function immediately starts up the connection. Who knows whether callbacks might trigger right away. Because there are so many arguments, and to prevent the need for ever new versions of this function, pass the arguments as an extendable struct. Change-Id: I6f181e42b678465bc9945f192559dc57d2083c6d
2020-04-302/2: wrap ipa_name in osmo_cni_peer_id with type enum and unionNeels Hofmeyr17-52/+217
To be prepared for the future in public API, wrap the new osmo_ipa_name struct in an enum-type and union called osmo_cni_peer. During code review it was requested to insert an ability to handle different kinds of peer id, in order to be able to add a Global Title in the future. Use the generic osmo_cni_peer only in the publicly visible API. For osmo-hlr internal code, I intend to postpone implementing this into the future, when a different peer identification actually gets introduced. This way we don't need to implement it now in all osmo-hlr code paths (save time now), but still make all external API users aware that this type may be extended in the future. Change-Id: Ide9dcdca283ab989240cfc6e53e9211862a199c5
2020-04-301/2: refactor: add and use lu_fsm, osmo_gsup_req, osmo_ipa_nameNeels Hofmeyr37-865/+1692
These are seemingly orthogonal changes in one patch, because they are in fact sufficiently intertwined that we are not willing to spend the time to separate them. They are also refactoring changes, unlikely to make sense on their own. ** lu_fsm: Attempting to make luop.c keep state about incoming GSUP requests made me find shortcomings in several places: - since it predates osmo_fsm, it is a state machine that does not strictly enforce the order of state transitions or the right sequence of incoming events. - several places OSMO_ASSERT() on data received from the network. - modifies the subscriber state before a LU is accepted. - dead code about canceling a subscriber in a previous VLR. That would be a good thing to actually do, which should also be trivial now that we record vlr_name and sgsn_name, but I decided to remove the dead code for now. To both step up the LU game *and* make it easier for me to integrate osmo_gsup_req handling, I decided to create a lu_fsm, drawing from my, by now, ample experience of writing osmo_fsms. ** osmo_gsup_req: Prepare for D-GSM, where osmo-hlr will do proxy routing for remote HLRs / communicate with remote MSCs via a proxy: a) It is important that a response that osmo-hlr generates and that is sent back to a requesting MSC contains all IEs that are needed to route it back to the requester. Particularly source_name must become destination_name in the response to be able to even reach the requesting MSC. Other fields are also necessary to match, which were so far taken care of in individual numerous code paths. b) For some operations, the response to a GSUP request is generated asynchronously (like Update Location Request -> Response, or taking the response from an EUSE, or the upcoming proxying to a remote HLR). To be able to feed a request message's information back into the response, we must thus keep the request data around. Since struct osmo_gsup_message references a lot of external data, usually with pointers directly into the received msgb, it is not so trivial to pass GSUP message data around asynchronously, on its own. osmo_gsup_req is the combined solution for both a and b: it keeps all data for a GSUP message by taking ownership of the incoming msgb, and it provides an explicit API "forcing" callers to respond with osmo_gsup_req_respond(), so that all code paths trivially are definitely responding with the correct IEs set to match the request's routing (by using osmo_gsup_make_response() recently added to libosmocore). Adjust all osmo-hlr code paths to use *only* osmo_gsup_req to respond to incoming requests received on the GSUP server (above LU code being one of them). In fact, the same should be done on the client side. Hence osmo_gsup_req is implemented in a server/client agnostic way, and is placed in libosmo-gsupclient. As soon as we see routing errors in complex GSUP setups, using osmo_gsup_req in the related GSUP client is likely to resolve those problems without much thinking required beyond making all code paths use it. libosmo-gsupclient is hence added to osmo-hlr binary's own library dependencies. It would have been added by the D-GSM proxy routing anyway, we are just doing it a little sooner. ** cni_peer_id.c / osmo_ipa_name: We so far handle an IPA unit name as pointer + size, or as just pointer with implicit talloc size. To ease working with GSUP peer identification data, I require: - a non-allocated storage of an IPA Name. It brings the drawback of being size limited, but our current implementation is anyway only able to handle MSC and SGSN names of 31 characters (see struct hlr_subscriber). - a single-argument handle for IPA Name, - easy to use utility functions like osmo_ipa_name_to_str(), osmo_ipa_name_cmp(), and copying by simple assignment, a = b. Hence this patch adds a osmo_ipa_name in cni_peer_id.h and cni_peer_id.c. Heavily used in LU and osmo_gsup_req. Depends: libosmocore Id9692880079ea0f219f52d81b1923a76fc640566 Change-Id: I3a8dff3d4a1cbe10d6ab08257a0138d6b2a082d9
2020-04-16Cosmetic: mention OS#4491 in location cancel codeOliver Smith2-2/+2
Change-Id: Idce0816172b92699d86ba3574a4fded0b73333cf
2020-04-11configure.ac: fix libtool issue with clang and sanitizerEric1-0/+5
As pointed out at https://github.com/libexpat/libexpat/issues/312 libtool does not play nice with clang sanitizer builds at all. For those builds LD shoud be set to clang too (and LDFLAGS needs the sanitizer flags as well), because the clang compiler driver knows how linking to the sanitizer libs works, but then at a later stage libtool fails to actually produce the shared libraries and the build fails. This is fixed by this patch. Addtionally LD_LIBRARY_PATH has no effect on conftest runs during configure time, so the rpath needs to be set to the asan library path to ensure the configure run does not fail due to a missing asan library, i.e.: SANS='-fsanitize=memory -fsanitize-recover=all -shared-libsan' export CC=clang-10 ASANPATH=$(dirname `$CC -print-file-name=libclang_rt.asan-x86_64.so`) export LDFLAGS="-Wl,-rpath,$ASANPATH $SANS $LDFLAGS" Change-Id: Ib98b84ac156f52ecdbb7ae49eaaea35442527b22
2020-02-14mslookup_client_mdns_test: no automatic skipOliver Smith1-2/+2
Exit with error code if multicast is disabled. The test is disabled by default already, so when explicitly enabling it, we should not automatically skip it. Related: OS#4385 Change-Id: I82022c23fa9c40535f922b12d917efd7e229912b
2020-02-14mslookup_client_mdns_test: disable by defaultOliver Smith4-8/+27
Only build and run the test, if --enable-mslookup-client-mdns-test is passed to ./configure. Enable that option in jenkins.sh. Related: OS#4385 Change-Id: Ie0cd4b0c55a1fbb00c215aeec7dcd0c15805add3
2020-02-09db: fix possible SQLite3 allocated memory leak in db_open()Vadim Yanitskiy1-1/+3
From https://sqlite.org/c3ref/exec.html: To avoid memory leaks, the application should invoke sqlite3_free() on error message strings returned through the 5th parameter of sqlite3_exec() after the error message string is no longer needed. If the 5th parameter to sqlite3_exec() is not NULL and no errors occur, then sqlite3_exec() sets the pointer in its 5th parameter to NULL before returning. Change-Id: Ic9ed9bad3165bc4a637fe963f51e923f012e19ac Fixes: CID#208182
2020-01-31mdns_rfc.c: fix possible access of uninit. memOliver Smith1-1/+6
Fixes: CID#207548 Change-Id: Ifa269d8a88d84c01349668cdd8d1f1d24c12c6d8
2020-01-29gsup_client.c: fix deprecation for client create funcNeels Hofmeyr1-8/+9
Change-Id: Iab9f416519b5df3bd4683592b2976f16675d9be7
2020-01-14mdns_sock.c: fix resource leak of sockOliver Smith1-5/+7
Fixes: CID#207542 Change-Id: I0216b17c3ff67910a39520e2f2a5a16e23575a86
2020-01-14osmo-mslookup-client: fix dereferencing nullOliver Smith1-0/+5
Fixes: CID#207543 Change-Id: Ia9ff5b2c767853dd00f577a7bc3583f408e061b5
2020-01-14osmo-mslookup-client.c: fix dereferencing nullOliver Smith1-3/+4
Fixes: CID#207544 Change-Id: I51b974420975e670708f0d2318f63615d281922c
2020-01-13mslookup_client_mdns.c: fix dereferencing nullOliver Smith1-0/+1
Fixes: CID#207545 Change-Id: I0f7fbbdb663304bd5214cba4a6e4abe1dd165cfa
2020-01-13mdns_msg.c: always call va_endOliver Smith1-1/+1
Fixes: CID#207546 Change-Id: I39829e78619a6412618e1140ff9b1185bad975bd
2020-01-13mslookup_client.c: fix dereferencing null pointerOliver Smith1-1/+1
Fixes: CID#207547 Change-Id: If19e1e68fad76a3d65788ac208da7dde1f8745c1
2020-01-13fix missing braces in LOGP_GSUP_FWDNeels Hofmeyr1-5/+5
Change-Id: I8634ea8822c8ccba4081014c5540f2b6a229fc7e
2020-01-13contrib/dgsm/ add example esme and dialplanOliver Smith3-0/+237
Add example scripts for the distributed GSM network: esme_dgsm.py: connect to the SMPP port of OsmoMSC A and forward SMS to the SMPP port of OsmoMSC B. The IP and port of OsmoMSC B is retrieved by the receiver's MSISDN using osmo-mslookup-client. contrib/dgsm/freeswitch_dialplan_dgsm.py: resolve the destination SIP servers of calls with osmo-mslookup-client and bridge the calls accordingly. For a detailed overview of the D-GSM and mslookup related files, please see the elaborate comment at the top of mslookup.c (already added in an earlier patch). Related: OS#4254 Related: OS#4255 Change-Id: I26e8dd8d9a08187fccb3e74ee91366bc24f6c608
2020-01-13add osmo-mslookup-client program (#2)Neels Hofmeyr8-1/+957
Standalone program using libosmo-mslookup to easily integrate with programs that want to connect services (SIP, SMS,...) to the current location of a subscriber. Also useful for manual testing. For a detailed overview of the D-GSM and mslookup related files, please see the elaborate comment at the top of mslookup.c (already added in an earlier patch). Resubmit of 637bbfcd9275f8c47212b29b50110f56ba6397bf after revert in 41fe3625915c456513544b99ba8c057c0f650b3c. Change-Id: Ie39d30e20461ab10ae3584863d8bfc6b76a12f37
2020-01-13add mDNS lookup method to libosmo-mslookup (#2)Oliver Smith22-0/+2864
Add the first actually useful lookup method to the mslookup library: multicast DNS. The server side is added in a subsequent commit, when the mslookup server is implemented for the osmo-hlr program. Use custom DNS encoding instead of libc-ares (which we use in OsmoSGSN already), because libc-ares is only a DNS client implementation and we will need both client and server. Resubmit of f10463c5fc6d9e786ab7c648d99f7450f9a25906 after being reverted in 110a49f69f29fed844d8743b76fd748f4a14812a. This new version skips the mslookup_client_mdns test if multicast is not supported in the build environment. I have verified that it doesn't break the build anymore in my own OBS namespace. Related: OS#4237, OS#4361 Patch-by: osmith, nhofmeyr Change-Id: I3c340627181b632dd6a0d577aa2ea2a7cd035c0c
2020-01-13Makefile.am: fix pkgconfig_DATAOliver Smith1-1/+2
Fix building debian packages: dh_install: Cannot find (any matches for) "usr/lib/*/pkgconfig/libosmo-mslookup.pc" (tried in "." and "debian/tmp") dh_install: libosmo-mslookup-dev missing files: usr/lib/*/pkgconfig/libosmo-mslookup.pc dh_install: missing files, aborting Fixes: bf7deda0fc30 ("add libosmo-mslookup abstract client") Change-Id: Ib0bce2d09b41834f7331969eaf7c57a9787f7efb
2020-01-12Revert "add mDNS lookup method to libosmo-mslookup"Harald Welte22-2829/+0
This reverts commit f10463c5fc6d9e786ab7c648d99f7450f9a25906, as it causes all OBS osmo-hlr builds to fail in the mslookup_client_mdns test. Change-Id: I5aec5b59f304c7f732c4a31131beedf29c966d9d
2020-01-12Revert "add osmo-mslookup-client program"Harald Welte8-957/+1
This reverts commit 637bbfcd9275f8c47212b29b50110f56ba6397bf, as it is a follow-up commit to Change-Id I03a0ffa1d4dc1b24ac78a5ad0975bca90a49c728 which causes all OBS osmo-hlr builds to fail in the mslookup_client_mdns test. Change-Id: I43084ac3b24684f17df43fefc82019e44baaa236
2020-01-11hlr: remove unused internal USSD listAlexander Couzens2-2/+0
struct hlr.iuse_list is not used at all. Change-Id: I7b51c195bbc107beb0a0bde72b266757fc4fd5e2
2020-01-10add osmo-mslookup-client programNeels Hofmeyr8-1/+957
Standalone program using libosmo-mslookup to easily integrate with programs that want to connect services (SIP, SMS,...) to the current location of a subscriber. Also useful for manual testing. For a detailed overview of the D-GSM and mslookup related files, please see the elaborate comment at the top of mslookup.c (already added in an earlier patch). Change-Id: Ie68a5c1db04fb4dff00dc3c774a1162f5b9fabf7
2020-01-10add mDNS lookup method to libosmo-mslookupOliver Smith22-0/+2829
Add the first actually useful lookup method to the mslookup library: multicast DNS. The server side is added in a subsequent commit, when the mslookup server is implemented for the osmo-hlr program. Use custom DNS encoding instead of libc-ares (which we use in OsmoSGSN already), because libc-ares is only a DNS client implementation and we will need both client and server. Related: OS#4237 Patch-by: osmith, nhofmeyr Change-Id: I03a0ffa1d4dc1b24ac78a5ad0975bca90a49c728
2020-01-10add libosmo-mslookup abstract clientOliver Smith24-3/+1622
mslookup is a key concept in Distributed GSM, which allows querying the current location of a subscriber in a number of cooperating but independent core network sites, by arbitrary service names and by MSISDN/IMSI. Add the abstract mslookup client library. An actual lookup method (besides mslookup_client_fake.c) is added in a subsequent patch. For a detailed overview of this and upcoming patches, please see the elaborate comment at the top of mslookup.c. Add as separate library, libosmo-mslookup, to allow adding D-GSM capability to arbitrary client programs. osmo-hlr will be the only mslookup server implementation, added in a subsequent patch. osmo-hlr itself will also use this library and act as an mslookup client, when requesting the home HLR for locally unknown IMSIs. Related: OS#4237 Patch-by: osmith, nhofmeyr Change-Id: I83487ab8aad1611eb02e997dafbcb8344da13df1
2020-01-10hlr: respect the num_auth_vectors requestedAlexander Couzens1-1/+6
Previous the hlr always returned the maximum possible auth vectors (5) to the client. Even when only asked for a single auth vector. Change-Id: I20c2b648456bc7ba1fc1321a7d42852158a3523c
2020-01-03Bump version: 1.1.0.26-276c-dirty → 1.2.01.2.0Pau Espin Pedrol2-4/+46
Change-Id: I5778895237511c62903784e8bed6920ecf058a50
2019-12-10tests/auc: change back to python3osmith/fix-python3Oliver Smith2-3/+2
Change the interpreter of the python script back to python3, as it was when the script was initially added in Idff9d757ab956179aa41ada2a223fd9f439aafbd. In the meantime, it had been changed to python2 to make it work with build slaves that were missing python3, but this is not necessary anymore. This should be merged shortly after osmo-python-tests was migrated to python3, and the jenkins build slaves were (automatically) updated to have the new osmo-python-tests installed. Related: OS#2819 Depends: osmo-python-tests I3ffc3519bf6c22536a49dad7a966188ddad351a7 Change-Id: Ifbb8f8f5428657a1c2d4d6d1217f8e374be43aba
2019-12-03hlr: exit(2) on unsupported positional arguments on command lineHarald Welte1-0/+5
Change-Id: I0c2738d380a7e79622fb3db2062c17782555e82d
2019-12-03gsup_client.h: fix license header: GPLv2+Oliver Smith1-6/+5
gsup_client.c is GPLv2 too, having AGPLv3 in the header file does not make sense. Change-Id: I3827a7c70d60137ffc654c1ca53c2652bb3df147
2019-12-01AUC: Add support for setting the AMF separation bit to '1' for EUTRANHarald Welte5-16/+26
Despite LTE/EUTRAN using the same authentication procedure (UMTS AKA) as 3G, there's one difference: The "operator defined" 16bit AMF field is reduced to 15 bits, with the first bit now being used as 'separation bit'. That bit should be '0' for 2G/3G (as it is right now) and '1' for authentication vectores generated for authentication over EUTRAN/EPS. Depends: libosmocore I93850710ab55a605bf61b95063a69682a2899bb1 (OSMO_GSUP_RAT_TYPES_IE) Change-Id: Ic766bc40f6126bb479bd0a05b0e96bec3e240008
2019-11-27db v4: add column last_lu_seen_psNeels Hofmeyr6-32/+76
Location Updating procedures from both CS and PS overwrite the same last_lu_seen field of a subscriber. For upcoming D-GSM it will be important to distinguish those, because only CS attaches qualify for MSISDN lookup. Add column last_lu_seen_ps, and upon PS LU, do not overwrite last_lu_seen, so that last_lu_seen now only reflects CS LU. In the VTY, dump both LU dates distinctively. Change-Id: Id7fc50567211a0870ac0524f6dee94d4513781ba
2019-11-25test_nodes.vty: tweak: add some '?' checksNeels Hofmeyr1-3/+47
I added these "by accident" when implementing D-GSM related VTY tests, now submitting them separately. Change-Id: I92a4245cae806270b00330403cc114017ab7af53
2019-11-25remove gsup_testNeels Hofmeyr7-145/+0
The test doesn't do much: it encodes an Insert Subscriber Data request for the sole purpose to ensure the msgb is allocated large enough. A bug like that is easily avoided statically. Also, the lu functions will get refactored soon, it doesn't make sense to me to drag this test along. Change-Id: I42e1c72bf4cce8034f968cd4392773bf2b643c1b