
CHANGE LOG OF SNMP4J-UNIX-TRANSPORT
===================================

[2026-08-02] Version 1.2.2:

* Fixed: UnixSocketStreamTransportMapping ignored isServerEnabled() and bound its socket path even in client
  mode, unlike DefaultTcpTransportMapping and TLSTM, which bind their listen address only if the server is
  enabled. A client mode transport mapping that opens outgoing connections only - as created for instance by
  AgentXSubagent.addMaster(..), which explicitly calls setServerEnabled(false) - therefore competed for the
  socket path of the transport mapping that serves incoming connections on it. An IP based transport mapping
  can bind an ephemeral port in that situation, but a Unix domain socket path is the address itself, so
  listen() failed with "Address already in use" as soon as both transport mappings used the same path. To
  keep the previous behavior for transport mappings that are used as a server, the constructor that takes a
  listen address enables the server mode now, as the corresponding constructor of DefaultTcpTransportMapping
  does. Use the new UnixSocketStreamTransportMapping(UnixDomainAddress,boolean) constructor or
  setServerEnabled(false) for a client mode transport mapping.
* Added: A client mode UnixSocketStreamTransportMapping (see setServerEnabled(boolean)) binds its socket
  path to the outgoing socket of every connection it opens, so that the peer can tell this SNMP entity
  apart from other entities that connect to it. A Unix domain socket that has not been bound has no address
  at all, thus all peers that connect with an unbound socket are reported with the same empty address by the
  accepting entity, which keeps its connections in a map that is keyed by that address: only the connection
  that arrived last could be addressed. Several AgentX sub-agents can therefore share one Unix domain master
  agent now, as long as each of them uses its own socket path. If the path cannot be bound, the connection
  is opened with an unbound socket as before and a warning is logged, and an entity that accepts a
  connection from an unbound socket logs a warning as well. New API:
  UnixSocketStreamTransportMapping.ServerThread.bindOutgoingSocket(SocketChannel).
* Fixed: UnixSocketStreamTransportMapping.close() removed the socket file of its listen address even if it
  had not created that file, which could remove the socket of another SNMP entity that used the same path.
  Only a socket file that this transport mapping has bound itself is removed now (see the new
  removeBoundSocketFile() method and the boundSocketPath member). close() also skipped closing the transport
  mapping altogether if it had no listen address.
* Fixed: UnixSocketStreamTransportMapping.listen() logged that the listen address had been bound
  successfully even if nothing had been bound at all, which is the case in client mode and for a transport
  mapping without a listen address (for example one created by GenericAddress.newLocalAddress("unix"), whose
  address is empty). It reports the actual outcome now.
* Fixed: UnixDomainAddress.isValid() and parseAddress(String) threw a NullPointerException for a socket path
  that has no parent path element, that is for a plain socket file name like "snmp4j-agent.sock" - the natural
  form for a socket in the working directory - as well as for the empty path and for a file system root. Such
  an address could therefore not be parsed at all, because GenericAddress.parse(String) discards an address
  whose parsing throws an exception. isValid() also threw a NullPointerException if no socket path had been
  set at all.
* Fixed: UnixDomainAddress.isValid() does not check file system permissions anymore. It checks now that the
  socket path is not empty and that it fits into the sun_path member of the sockaddr_un structure of the
  operating system (see the new MAX_SOCKET_PATH_LENGTH constant), because those are the properties of the
  address itself. Before, it required write and search permission on the directory of the socket path, which
  is what binding a socket needs but not what connecting to one needs: an existing socket in a read-only
  directory (for example, below /var/run) was reported as invalid, although it can be connected, whereas a
  socket file without write permission for the SNMP4J process was reported as valid although connecting to it
  fails with "Permission denied". As a consequence, parseAddress(String) does not depend on the current
  working directory, on the effective user of the process, and on the state of the file system anymore. An
  over-long socket path is rejected now, which was accepted before, although it cannot be bound.
* Fixed: UnixDomainAddress.parseAddress(String) returns false instead of throwing an InvalidPathException if
  the supplied address contains a NUL character, and false instead of throwing a NullPointerException if the
  supplied address is null.
* Added: New org.snmp4j.transport.unix.audit package with the UnixDomainAgentProfilePolicy, a subclass of the
  DefaultAgentAuditPolicy of SNMP4J-Agent that supports the "unix" address domain of UnixDomainAddress.
  Because a Unix domain socket operation is always local, the InetAddress based network access restrictions
  of the AgentPolicyProfile are not applicable to it and the file system access that such an operation needs
  is checked instead: the socket's (local) file path is matched against the allowed files and directories of
  the profile, where LISTEN is checked as a CREATE, CLOSE as a DELETE, SEND as a WRITE, and RECEIVE as a READ
  file operation. Transport operations of other address domains are audited by the DefaultAgentAuditPolicy
  unchanged. The new optional (provided) dependency to SNMP4J-Agent is required for this package only.
* Added: UnixDomainAddress.isBindable() and UnixDomainAddress.isConnectable() check whether the current
  process may listen on respectively send to a Unix domain socket address, using the permissions that the
  corresponding operation actually requires: write and search permission on the socket's directory to bind it
  and write permission on the socket file to connect to it. Because both are a snapshot of the current file
  system state, a failing bind or connect still has to be handled. In addition,
  UnixDomainAddress.getParentDirectory() returns the absolute directory that contains the socket file and
  UnixDomainAddress.MAX_SOCKET_PATH_LENGTH provides the maximum length of a Unix domain socket path in bytes.
* Updated: Dependency to SNMP4J to 3.13.1 and SNMP4J-Agent to 3.10.1.

[2026-07-29] Version 1.2.1:

* Fixed: TransportAuditListener was not checking/fireing LISTEN, SEND, and CLOSE events. RECEIVE events were already
  checked and fired properly.
* Updated: Dependency to SNMP4J to 3.13.0.

[2026-07-21] Version 1.2.0:

* Updated: Dependency to SNMP4J to 3.12.2. Implemented the new interfaces for WorkerTask (shutdown() and join(long))
  and AbstractConnectionOrientedTransportMapping.setSocketOption(..) introduced in SNMP4J 3.10.0.
* Updated all Maven dependencies to their latest versions.

[2024-04-02] Version 1.1.0:

* Updated: Dependency to SNMP4J to 3.8.0.
* Fixed: Possible NullPointerException when calling UnixDomainAddress.getPath() if unixDomainAddress is null,
  which might be the case for local addresses.

[2022-10-08] Version 1.0.2:

* Updated: Dependency to SNMP4J to 3.7.3.

[2022-10-04] Version 1.0.1:

* Initial version.
