| 801 | } |
| 802 | |
| 803 | void NetDb::HandleDatabaseStoreMsg (std::shared_ptr<const I2NPMessage> m) |
| 804 | { |
| 805 | const uint8_t * buf = m->GetPayload (); |
| 806 | size_t len = m->GetSize (); |
| 807 | if (len < DATABASE_STORE_HEADER_SIZE) |
| 808 | { |
| 809 | LogPrint (eLogError, "NetDb: Database store msg is too short ", len, ". Dropped"); |
| 810 | return; |
| 811 | } |
| 812 | IdentHash ident (buf + DATABASE_STORE_KEY_OFFSET); |
| 813 | if (ident.IsZero ()) |
| 814 | { |
| 815 | LogPrint (eLogDebug, "NetDb: Database store with zero ident, dropped"); |
| 816 | return; |
| 817 | } |
| 818 | uint32_t replyToken = bufbe32toh (buf + DATABASE_STORE_REPLY_TOKEN_OFFSET); |
| 819 | size_t offset = DATABASE_STORE_HEADER_SIZE; |
| 820 | if (replyToken) |
| 821 | { |
| 822 | if (len < offset + 36) // 32 + 4 |
| 823 | { |
| 824 | LogPrint (eLogError, "NetDb: Database store msg with reply token is too short ", len, ". Dropped"); |
| 825 | return; |
| 826 | } |
| 827 | uint32_t tunnelID = bufbe32toh (buf + offset); |
| 828 | offset += 4; |
| 829 | if (replyToken != 0xFFFFFFFFU) // if not caught on OBEP or IBGW |
| 830 | { |
| 831 | IdentHash replyIdent(buf + offset); |
| 832 | auto deliveryStatus = CreateDeliveryStatusMsg (replyToken); |
| 833 | if (!tunnelID) // send response directly |
| 834 | transports.SendMessage (replyIdent, deliveryStatus); |
| 835 | else |
| 836 | { |
| 837 | bool direct = true; |
| 838 | if (!i2p::transport::transports.IsConnected (replyIdent)) |
| 839 | { |
| 840 | auto r = FindRouter (replyIdent); |
| 841 | if (r && !r->IsReachableFrom (i2p::context.GetRouterInfo ())) |
| 842 | direct = false; |
| 843 | } |
| 844 | if (direct) // send response directly to IBGW |
| 845 | transports.SendMessage (replyIdent, i2p::CreateTunnelGatewayMsg (tunnelID, deliveryStatus)); |
| 846 | else |
| 847 | { |
| 848 | // send response through exploratory tunnel |
| 849 | auto pool = i2p::tunnel::tunnels.GetExploratoryPool (); |
| 850 | auto outbound = pool ? pool->GetNextOutboundTunnel () : nullptr; |
| 851 | if (outbound) |
| 852 | outbound->SendTunnelDataMsgTo (replyIdent, tunnelID, deliveryStatus); |
| 853 | else |
| 854 | LogPrint (eLogWarning, "NetDb: No outbound tunnels for DatabaseStore reply found"); |
| 855 | } |
| 856 | } |
| 857 | } |
| 858 | offset += 32; |
| 859 | } |
| 860 | // we must send reply back before this check |
nothing calls this directly
no test coverage detected