Q2NS dev
ns-3 module
Loading...
Searching...
No Matches
q2ns-swap-app.h
Go to the documentation of this file.
1/*-----------------------------------------------------------------------------
2 * Q2NS - Quantum Network Simulator
3 * Copyright (c) 2026 quantuminternet.it
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *---------------------------------------------------------------------------*/
9/**
10 * @file q2ns-swap-app.h
11 * @brief Declares q2ns::SwapApp, the entanglement-swapping ns-3 Application.
12 */
13#pragma once
14
15#include "ns3/application.h"
16#include "ns3/ipv4-address.h"
17#include "ns3/ipv6-address.h"
18#include "ns3/packet-sink.h"
19#include "ns3/ptr.h"
20#include "ns3/traced-callback.h"
21
22#include <cstdint>
23#include <memory>
24#include <string>
25#include <unordered_map>
26#include <vector>
27
28namespace ns3 {
29class Packet;
30class PacketSink;
31class Socket;
32} // namespace ns3
33
34namespace q2ns {
35
36class QNode;
37class NetController;
38class Qubit;
39
40class SwapApp final : public ns3::Application {
41public:
42 enum class Role : uint8_t { Prev = 0, Repeater = 1, Next = 2 };
43
45 uint64_t sid{0};
47 ns3::Time start{ns3::Seconds(0.0)};
48 std::string proto{"udp"}; // "udp" | "tcp"
49 uint16_t ctrlPort{7000};
50
51 // Repeater-specific
52 uint64_t prevPeerId{0};
53 uint64_t nextPeerId{0};
54 ns3::Ipv4Address prevEndAddr{ns3::Ipv4Address("0.0.0.0")};
55 ns3::Ipv4Address nextEndAddr{ns3::Ipv4Address("0.0.0.0")};
56 ns3::Ipv6Address prevEndAddr6{ns3::Ipv6Address::GetAny()};
57 ns3::Ipv6Address nextEndAddr6{ns3::Ipv6Address::GetAny()};
58
59 // Endpoint-specific
60 uint64_t expectedMsgs{1}; // number of repeater BSM packets to XOR
61 bool genPrev{false}; // generate the prev link and send remote to prev neighbor
62 bool genNext{false}; // generate the next link and send remote to next neighbor
63 bool applyCorrections{false}; // only true on Sink
64
65 bool verifyFidelity{false};
66 double verifyThreshold{0.90};
67 };
68
69 // Classical network info
70 void SetPayloadBytes(uint32_t n) {
72 }
73 void SetUseIpv6(bool v6) {
74 m_useIpv6 = v6;
75 }
76 void SetPeerAddress(ns3::Ipv4Address v4) {
77 m_peerV4 = v4;
78 }
79 void SetPeerAddress6(ns3::Ipv6Address v6) {
80 m_peerV6 = v6;
81 }
82
83 static ns3::TypeId GetTypeId();
84
85 SwapApp() = default;
86 ~SwapApp() override = default;
87
88 // ns3::Application
89 void StartApplication() override;
90 void StopApplication() override;
91
92 // External wiring
94 m_nc = nc;
95 }
96
97 // Add one session (may be called multiple times before StartApplication or during sim setup)
98 void AddSession(const SessionConfig& cfg);
99
100 // Traces (include sid to avoid per-session trace creation)
101 ns3::TracedCallback<uint64_t, ns3::Time> m_traceRoundStart; // repeater/endpoint sees its start
102 ns3::TracedCallback<uint64_t, ns3::Time, uint8_t, uint8_t> m_traceBSMDone; // repeater BSM done
103 ns3::TracedCallback<uint64_t, ns3::Time, uint8_t, uint8_t> m_traceCtrlSent; // repeater sends bits
104 ns3::TracedCallback<uint64_t, ns3::Time, uint8_t, uint8_t>
105 m_traceFrameResolved; // endpoint frame ready
106 ns3::TracedCallback<uint64_t, ns3::Time> m_traceCorrectionApplied; // endpoint applied Pauli
107 ns3::TracedCallback<uint64_t, ns3::Time, double> m_traceVerifyFidelity;
108
109
110private:
113
114 // Endpoint state
115 std::shared_ptr<q2ns::Qubit> targetQubit;
116 bool haveQ{false};
117 bool haveF{false};
118 bool done{false};
119 uint8_t accumM1{0}, accumM2{0};
120 uint32_t recv{0};
121
122 // Repeater state
123 std::shared_ptr<Qubit> qPrev; // the qubit tied to the prev link at this repeater
124 std::shared_ptr<Qubit> qNext; // the qubit tied to the next link at this repeater
125 bool haveBSM{false};
126 };
127
129
130 // All sessions on this node
131 std::unordered_map<uint64_t, SessionState> m_sessions; // keyed by sid
132
133 // Control-plane sinks per port
134 std::unordered_map<uint16_t, ns3::Ptr<ns3::PacketSink>> m_sinksByPort;
135
136 uint32_t m_payloadBytes{16}; // defaults to small
137 bool m_useIpv6{false};
138 ns3::Ipv4Address m_peerV4;
139 ns3::Ipv6Address m_peerV6;
140
141 // Internal helpers
142 void ScheduleSession(const SessionState& s);
145
146 void OnCtrlRx(ns3::Ptr<const ns3::Packet> pkt, const ns3::Address& from);
147 void EnsureSink(uint16_t port, const std::string& proto);
148
149 // Repeater BSM attempt
151
152 void TryApply(SessionState& s);
153
154 // TCP helpers (UDP is default)
155 void OnTcpConnected(ns3::Ptr<ns3::Socket> s);
156 void OnTcpConnectFail(ns3::Ptr<ns3::Socket> s);
157
158
159 std::unordered_map<uint16_t, ns3::Ptr<ns3::Socket>> m_udp4; // keyed by local send port (optional)
160 std::unordered_map<uint16_t, ns3::Ptr<ns3::Socket>> m_udp6;
161 struct TcpKey {
162 bool v6;
163 uint16_t port;
164
165 std::string dst;
166 bool operator==(const TcpKey& o) const {
167 return v6 == o.v6 && port == o.port && dst == o.dst;
168 }
169 };
170 struct TcpKeyHash {
171 size_t operator()(const TcpKey& k) const {
172 return std::hash<std::string>()(k.dst) ^ (k.port << 1) ^ (k.v6 ? 0x9e37 : 0);
173 }
174 };
175 std::unordered_map<TcpKey, ns3::Ptr<ns3::Socket>, TcpKeyHash> m_tcp;
176
177 std::unordered_map<uintptr_t, ns3::Ptr<ns3::Packet>>
178 m_tcpPendingOnce; // existing is fine to re-use
179
180 std::unordered_map<uintptr_t, ns3::Ptr<ns3::Packet>>
181 m_tcpPending; // Pending ctrl packets keyed by socket pointer (unique per socket)
182
183 std::unordered_map<TcpKey, ns3::Ptr<ns3::Socket>, TcpKeyHash> m_udp6_conn;
184 ns3::Ptr<ns3::Socket> GetOrCreateUdpV6Connected(const ns3::Ipv6Address& dst, uint16_t port);
185
186 ns3::Ptr<ns3::Socket> GetOrCreateUdpSender(uint16_t port, bool v6);
187 ns3::Ptr<ns3::Socket> GetOrCreateTcpSender(const ns3::Address& dst, bool v6, uint16_t port);
188};
189
190} // namespace q2ns
Main user-facing facade for creating and configuring a quantum network.
void StopApplication() override
ns3::Ptr< ns3::Socket > GetOrCreateUdpSender(uint16_t port, bool v6)
void SetPeerAddress6(ns3::Ipv6Address v6)
std::unordered_map< TcpKey, ns3::Ptr< ns3::Socket >, TcpKeyHash > m_udp6_conn
ns3::Ipv4Address m_peerV4
uint32_t m_payloadBytes
NetController * m_nc
std::unordered_map< TcpKey, ns3::Ptr< ns3::Socket >, TcpKeyHash > m_tcp
std::unordered_map< uint16_t, ns3::Ptr< ns3::PacketSink > > m_sinksByPort
~SwapApp() override=default
static ns3::TypeId GetTypeId()
void StartApplication() override
void EnsureSink(uint16_t port, const std::string &proto)
void OnTcpConnected(ns3::Ptr< ns3::Socket > s)
ns3::Ptr< ns3::Socket > GetOrCreateTcpSender(const ns3::Address &dst, bool v6, uint16_t port)
void TryApply(SessionState &s)
std::unordered_map< uintptr_t, ns3::Ptr< ns3::Packet > > m_tcpPending
void SetPayloadBytes(uint32_t n)
std::unordered_map< uint16_t, ns3::Ptr< ns3::Socket > > m_udp4
std::unordered_map< uint64_t, SessionState > m_sessions
void DoEndpointStart(SessionState &s)
void AddSession(const SessionConfig &cfg)
std::unordered_map< uint16_t, ns3::Ptr< ns3::Socket > > m_udp6
void MaybeDoBsmAndAnnounce(SessionState &s)
ns3::Ipv6Address m_peerV6
std::unordered_map< uintptr_t, ns3::Ptr< ns3::Packet > > m_tcpPendingOnce
void OnTcpConnectFail(ns3::Ptr< ns3::Socket > s)
void SetUseIpv6(bool v6)
void ScheduleSession(const SessionState &s)
void DoRepeaterRound(SessionState &s)
void SetNetController(NetController *nc)
ns3::TracedCallback< uint64_t, ns3::Time, uint8_t, uint8_t > m_traceBSMDone
ns3::TracedCallback< uint64_t, ns3::Time, double > m_traceVerifyFidelity
void OnCtrlRx(ns3::Ptr< const ns3::Packet > pkt, const ns3::Address &from)
ns3::TracedCallback< uint64_t, ns3::Time, uint8_t, uint8_t > m_traceFrameResolved
ns3::TracedCallback< uint64_t, ns3::Time, uint8_t, uint8_t > m_traceCtrlSent
ns3::TracedCallback< uint64_t, ns3::Time > m_traceRoundStart
ns3::Ptr< ns3::Socket > GetOrCreateUdpV6Connected(const ns3::Ipv6Address &dst, uint16_t port)
void SetPeerAddress(ns3::Ipv4Address v4)
SwapApp()=default
ns3::TracedCallback< uint64_t, ns3::Time > m_traceCorrectionApplied
ns3::Ipv6Address nextEndAddr6
ns3::Ipv6Address prevEndAddr6
std::shared_ptr< Qubit > qNext
std::shared_ptr< q2ns::Qubit > targetQubit
std::shared_ptr< Qubit > qPrev
size_t operator()(const TcpKey &k) const
bool operator==(const TcpKey &o) const