Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [mosquitto-dev] Basic configuration issue with multiple listeners

Greg

On 12/08/2019 17:26, Greg Troxel wrote:
...snip
My mosquitto configuration file (/etc/mosquitto/mosquitto.conf) is the
default installed version. On top of this, I have a local config file
in /etc/mosquitto/conf.d that contains the following:

allow_anonymous false
connection_messages true
log_dest syslog
log_type error
log_type warning
password_file /etc/mosquitto/passwd
socket_domain ipv4
'A'


A major source of difficulty for me is how mosquitto does listener
configuration.   A listener in other configs would be configured as a
stanza that has the listener and the things that control it scoped
somehow.
Yes. I have looked longingly at HiveMQ's use of XML configuration files :-)
mosquitto sort of has the listener directive and then the
things that follow modify that listener, until the next  listener.  And
if you have modifier statement before the first new listener, it makes
the default listener be active and then modifies it.   I think this is
basically a bug, but I realize it is hard to change.

This is the critical piece of information! Thank, Greg! :-)
This works fine as verified with mosquitto_sub/pub, plus 'netstat
-tlpn' lists an LISTEN port associated with the mosquitto process.
The key point is to see if this is bound to *.1883 or 127.0.0.1.1883.
The normal listen binds to INADDR_ANY, which is represented 0.0.0.0, and
matches all addresses.
Great call! My only mosquitto listener was 0.0.0.0:1883. Don't know how I missed that! :-[

This also clarifies for me how mosquitto handles the default listener. I was imagining some crazy process of seeking out all available interfaces and creating a listener for each... but I was overlooking the wildcard IP address.

From my reading of the docs  & what I *want* to achieve, I would have
thought that the following should work for me:

listener 1883 localhost
listener 1883 192.168.0.1
In fact, this now works! See below...
...snip
EADDRINUSE means that a call to bind() failed, and that can be because
it tried to bind INADDR_ANY first and then a specific address, or
because there were two binds to INADDR_ANY.  Perhaps use some kind of
ktrace/strace/ktruss type program to see what happens.
This appears to produce weird behaviour. When mosquitto has a default listener 'bound' to 0.0.0.0 and you attempt to bind the same IP address it seems to report an error and then trashes the listener you already had leaving with no listeners at all :-\

...snip

You're overlooking how hard it is to configure listeners in mosquitto,
and how much you have to be careful to avoid the implicit one.  :-(
Yep. Avoiding the default listener is key!
So look hard at the default config, and perhaps get rid of it, and
perhaps ask where it came from and why each line is as it is.
Working through the default conf file, this does not cause any problems.

...snip

The problem was my adding a "socket_domain ipv4" directive in my local conf file. That starts the default listener (not obvious that it should, but it does). The ultimate error is, IMO, bizarre. It appears that having inadvertently started the default listener bound to 0.0.0.0 (i.e. everything), in attempting to bind a second listener to a specific address (such as localhost), mosquitto seems to determine that localhost is a subset of 0.0.0.0 and fails with an "address already in use" error. This is not a very helpful diagnostic, IMO! To make matters worse, the default listener gets trashed in the process and you end up with nothing! 

So. In summary. Problem now solved! Greg's advice to avoid starting the default listener is critical. Given that,

listener 1883 localhost
listener 1883 192.168.0.1

does the business... as I thought it should! :-)

The corollary: Is mosquitto's hidden invocation of the default listener by innocuous-looking directives really the best approach? This looks to me like a side-effect waiting to bite you. Could starting the default listener be made explicit? Or indeed removed altogether? An explicit "listener 1883  0.0.0.0" directive would seem to do the same job but has the advantage of making it obvious what is happening?

Thanks,

Peter






Back to the top