2222import org .epics .pva .PVASettings ;
2323import org .epics .pva .common .AddressInfo ;
2424import org .epics .pva .common .Network ;
25+ import org .epics .pva .common .OriginTag ;
2526import org .epics .pva .common .PVAHeader ;
2627import org .epics .pva .common .SearchRequest ;
2728import org .epics .pva .common .SearchResponse ;
@@ -87,7 +88,6 @@ public interface SearchResponseHandler
8788 // with the understanding that it will only receive broadcasts;
8889 // since they are often blocked by firewall, may receive nothing, ever.
8990 private final DatagramChannel udp_beacon ;
90- private final ByteBuffer beacon_buffer = ByteBuffer .allocate (PVASettings .MAX_UDP_PACKET );
9191
9292 private volatile Thread search_thread4 , search_thread6 , beacon_thread ;
9393
@@ -100,20 +100,22 @@ public ClientUDPHandler(final BeaconHandler beacon_handler,
100100 // IPv4 socket, also used to send broadcasts and for the local re-sending
101101 udp_search4 = Network .createUDP (StandardProtocolFamily .INET , null , 0 );
102102 udp_search4 .socket ().setBroadcast (true );
103- local_multicast = Network .configureLocalIPv4Multicast (udp_search4 , PVASettings .EPICS_PVA_BROADCAST_PORT );
103+ local_multicast = Network .getLocalMulticastGroup (udp_search4 , PVASettings .EPICS_PVA_BROADCAST_PORT );
104104 udp_localaddr4 = (InetSocketAddress ) udp_search4 .getLocalAddress ();
105105
106106 String ipV6Msg ;
107107
108108 // IPv6 sockets
109109 // Beacon socket only receives, does not send broadcasts
110- if (PVASettings .EPICS_PVA_ENABLE_IPV6 ) {
110+ if (PVASettings .EPICS_PVA_ENABLE_IPV6 )
111+ {
111112 udp_search6 = Network .createUDP (StandardProtocolFamily .INET6 , null , 0 );
112113 udp_localaddr6 = (InetSocketAddress ) udp_search6 .getLocalAddress ();
113114 ipV6Msg = String .format (" and %s" , udp_localaddr6 );
114115 udp_beacon = Network .createUDP (StandardProtocolFamily .INET6 , null , PVASettings .EPICS_PVA_BROADCAST_PORT );
115116 }
116- else {
117+ else
118+ {
117119 udp_search6 = null ;
118120 udp_beacon = Network .createUDP (StandardProtocolFamily .INET , null , PVASettings .EPICS_PVA_BROADCAST_PORT );
119121 udp_localaddr6 = null ;
@@ -150,11 +152,8 @@ public void send(final ByteBuffer buffer, final AddressInfo info) throws Excepti
150152 }
151153 else
152154 {
153- if (!PVASettings .EPICS_PVA_ENABLE_IPV6 ) {
154- throw new Exception (
155- "EPICS_PVA_ENABLE_IPV6 must be enabled to use IPv6 address!"
156- );
157- }
155+ if (!PVASettings .EPICS_PVA_ENABLE_IPV6 )
156+ throw new Exception ("EPICS_PVA_ENABLE_IPV6 must be enabled to use IPv6 address!" );
158157
159158 synchronized (udp_search6 )
160159 {
@@ -177,13 +176,15 @@ public void start()
177176 search_thread4 .setDaemon (true );
178177 search_thread4 .start ();
179178
180- if (PVASettings .EPICS_PVA_ENABLE_IPV6 ) {
179+ if (PVASettings .EPICS_PVA_ENABLE_IPV6 )
180+ {
181181 final ByteBuffer receive_buffer6 = ByteBuffer .allocate (PVASettings .MAX_UDP_PACKET );
182182 search_thread6 = new Thread (() -> listen (udp_search6 , receive_buffer6 ), "UDP6-receiver " + Network .getLocalAddress (udp_search6 ));
183183 search_thread6 .setDaemon (true );
184184 search_thread6 .start ();
185185 }
186186
187+ final ByteBuffer beacon_buffer = ByteBuffer .allocate (PVASettings .MAX_UDP_PACKET );
187188 beacon_thread = new Thread (() -> listen (udp_beacon , beacon_buffer ), "UDP-beacon-receiver " + Network .getLocalAddress (udp_beacon ));
188189 beacon_thread .setDaemon (true );
189190 beacon_thread .start ();
@@ -197,6 +198,9 @@ protected boolean handleMessage(final InetSocketAddress from, final byte version
197198 {
198199 case PVAHeader .CMD_BEACON :
199200 return handleBeacon (from , version , payload , buffer );
201+ case PVAHeader .CMD_ORIGIN_TAG :
202+ // Will be decoded with CMD_SEARCH
203+ break ;
200204 case PVAHeader .CMD_SEARCH :
201205 return handleSearchRequest (from , version , payload , buffer );
202206 case PVAHeader .CMD_SEARCH_RESPONSE :
@@ -290,7 +294,8 @@ private boolean handleBeacon(final InetSocketAddress from, final byte version,
290294 private boolean handleSearchRequest (final InetSocketAddress from , final byte version ,
291295 final int payload , final ByteBuffer buffer )
292296 {
293- final SearchRequest search = SearchRequest .decode (from , version , payload , buffer );
297+ final OriginTag origin = OriginTag .testForOriginOfSearch (from , buffer );
298+ final SearchRequest search = SearchRequest .decode (origin , from , version , payload , buffer );
294299 try
295300 {
296301 if (local_multicast != null && search != null && search .unicast )
@@ -300,7 +305,8 @@ private boolean handleSearchRequest(final InetSocketAddress from, final byte ver
300305 if (search .reply_required )
301306 {
302307 forward_buffer .clear ();
303- SearchRequest .encode (false , 0 , null , search .client , search .tls , forward_buffer );
308+ OriginTag .encode (udp_search4 , forward_buffer );
309+ SearchRequest .encode (false , search .reply_to_src_port , 0 , null , search .client , search .tls , forward_buffer );
304310 forward_buffer .flip ();
305311 logger .log (Level .FINER , () -> "Forward search to list servers to " + local_multicast + "\n " + Hexdump .toHexdump (forward_buffer ));
306312 send (forward_buffer , local_multicast );
@@ -309,7 +315,8 @@ private boolean handleSearchRequest(final InetSocketAddress from, final byte ver
309315 else
310316 {
311317 forward_buffer .clear ();
312- SearchRequest .encode (false , search .seq , search .channels , search .client , search .tls , forward_buffer );
318+ OriginTag .encode (udp_search4 , forward_buffer );
319+ SearchRequest .encode (false , search .reply_to_src_port , search .seq , search .channels , search .client , search .tls , forward_buffer );
313320 forward_buffer .flip ();
314321 logger .log (Level .FINER , () -> "Forward search to " + local_multicast + "\n " + Hexdump .toHexdump (forward_buffer ));
315322 send (forward_buffer , local_multicast );
0 commit comments