Skip to content

Client and server unintentionally sharing a UDP source port #128

Open
@mdavidsaver

Description

@mdavidsaver
2018-09-27T11:48:07.986 Undecipherable message (bad response type 4) from 127.0.0.1:51856.

I've seen this pop up 4 times during 2 days of stress testing of P4P. I was able to catch one instance with wireshark and confirm that somehow the PVA client is sending UDP searches with the same source port number which the server is listening on. So src.port==dst.port. This causes the server to see it's own replies.

Since the client operation is timing out, I take it that there are two sockets with the same source port. I'm not sure if bind() to port zero can do this?

The structure of these tests is to start the server first, then the client.

            self.server = Server(providers=[self.sprov], isolate=True)
...
            with Context('pva', conf=self.server.conf(), useenv=False, unwrap={}) as ctxt:
                    ...

Where isolate=True is a shorthand for setting the following, which should cause the server to choose a random port by binding to port 0 then finding which ports are used.

{
                'EPICS_PVAS_INTF_ADDR_LIST': '127.0.0.1',
                'EPICS_PVA_ADDR_LIST': '127.0.0.1',
                'EPICS_PVA_AUTO_ADDR_LIST': '0',
                'EPICS_PVA_SERVER_PORT': '0',
                'EPICS_PVA_BROADCAST_PORT': '0',
}

The self.server.conf() is calling

Configuration::shared_pointer
ServerContextImpl::getCurrentConfig()
{
ConfigurationBuilder B;
std::ostringstream providerName;
for(size_t i=0; i<_channelProviders.size(); i++) {
if(i>0)
providerName<<" ";
providerName<<_channelProviders[i]->getProviderName();
}
#define SET(K, V) B.add(K, V);
{
char buf[50];
ipAddrToA(&_ifaceAddr.ia, buf, sizeof(buf));
buf[sizeof(buf)-1] = '\0';
SET("EPICS_PVAS_INTF_ADDR_LIST", buf);
}
SET("EPICS_PVAS_BEACON_ADDR_LIST", getBeaconAddressList());
SET("EPICS_PVA_ADDR_LIST", getBeaconAddressList());
SET("EPICS_PVAS_AUTO_BEACON_ADDR_LIST",
isAutoBeaconAddressList() ? "YES" : "NO");
SET("EPICS_PVA_AUTO_ADDR_LIST",
isAutoBeaconAddressList() ? "YES" : "NO");
SET("EPICS_PVAS_BEACON_PERIOD", getBeaconPeriod());
SET("EPICS_PVA_BEACON_PERIOD", getBeaconPeriod());
SET("EPICS_PVAS_SERVER_PORT", getServerPort());
SET("EPICS_PVA_SERVER_PORT", getServerPort());
SET("EPICS_PVAS_BROADCAST_PORT", getBroadcastPort());
SET("EPICS_PVA_BROADCAST_PORT", getBroadcastPort());
SET("EPICS_PVAS_MAX_ARRAY_BYTES", getReceiveBufferSize());
SET("EPICS_PVA_MAX_ARRAY_BYTES", getReceiveBufferSize());
SET("EPICS_PVAS_PROVIDER_NAMES", providerName.str());
#undef SET
return B.push_map().build();
}

Which is producing a Configuration which can be use to configure a PVA client.

Previously noted on #104 (comment)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions