Documentation‎ > ‎User Guide‎ > ‎

Dispatcher and Message Router Configuration

Dispatcher and Message Router configuration is done in a file named cobalt-router.conf located in the config directory. It is read in at viewer startup time and is used to configure the external connectivity, the authentication services and error logging. It's a file of Smalltalk code that returns a configuration object to the dispatcher, so it follows the Smalltalk syntax rules.

There are 4 types of stanzas/blocks that appear in the router config:  comments, dispatcher configuration, authentication, and logging setup.

The stanza we are concerned about takes a block argument that will return a dispatcher configuration ( dispatcherConfigBlock: ). In the shipped standard configuration file, the dispatcherBlock: is setup to configure a Universal Plug and Play firewall hole (if a UPnP accessible firewall router is available) using the TUpnpDispatcherConfig. 

Another option for the dispatcherConfigBlock: is "LAN only" with no port forwarding at all as it assumes the local machine addresses are the ones to advertise because you either are running entirely inside a LAN or you have public IP addresses (use TLanOnlyDispatcherConfig). There is also a fully manual config that assumes port forwards have been set up manually (use TManualDispatcherConfig).  These all can be sent the routerClass: method to set up the kind of router that gets spawned on connection. I expect we won't be changing the router type much but it's been useful for testing. There is also a localAddressString: method they all understand and as well as a dispatcherPort: method to set the TCP port used by the dispatcher. There are example configuration files illustrating these options in the example-config directory in the Open Cobalt installation.

The TLANOnlyDispatcherConfig also has the dispatcherPort: option to set the TCP port number the dispatcher listens to for incoming connections. If not set the default is 6900. The TManualDispatcherConfig has four other options: externalIp:, externalPort:, internalIp and internalPort:. Internal port is a synonym for dispatcherPort:, internalIp: is a synonym for localAddressString:. The options externalIp: and externalPort are the TCP/IP address and port that will be advertised to the external world, usually on the internet side of a firewall or NAT router.

The reason we have this setup in an external file instead of relying on autodetecting is that the Squeak TCP/IP interface has some problems and doesn't really understand that a machine can have multiple active TCP/IP interfaces....they seem to have made an assumption that there is only one interface active as would be common in a workstation.  Servers, or a workstation running VMware or Parallels will often have more than one active interface. If you ask for the local interface address, it will give back it's best guess....which is often wrong if you have multiple interfaces.  The localAddressString: method is there to specify the interface we want to advertise, in the cases where the automatic approach is giving us wrong answers.  In the shipped configuration file I have the localAddressString: send commented out, but if Cobalt Master isn't starting up properly try uncommenting it and setting the address string to the IP address you want to use, usually the default interface.  In testing has worked, it just won't let anyone else get a reasonable address to connect to you.

Example configuration file:

^(CobaltRouterConfig new)
    commentBlock: 'This is a comment, Open Cobalt will ignore it.';
    dispatcherConfigBlock: [
        "This is the
default config, it tries to automatically determine
            a working config. Still somewhat error prone"
            routerClass: CobaltMessageRouter ;
"localAddressString: '';"             yourself     ] ;     authServicesBlock: [ :services |         | userSrv ldapSrv |         services addService: ( CoLocalSecretTestAuthService named: 'Local' ).                 userSrv := CoUserDbAuthService named: 'Test User Database'.         userSrv             addUsername: 'root' password: 'testroot'  displayName: 'SuperUser' group: #wheel;             addUsername: 'bbuilder' password: 'testroot'  displayName: 'Bob the Builder' group: #builder;             addUsername: 'jruser' password: 'teatime'  displayName: 'J. Random User' group: #user ;             addUsername: 'foo' password: 'bar'  displayName: 'Test User' group: #wheel ;             addUsername: '' password: 'teatime'  displayName: 'Cobalt Test Jabber User' group: #wheel ;             addUsername: 'jdougan' password: 'teatime'  displayName: 'John Dougan' group: #wheel ;             addUsername: 'guest' password: 'guest'  displayName: 'Guest User' group: #ghost.         services addService: userSrv.         services authorizationService: userSrv.     ] ;     logBlock: [ :log |         | filelog |         log adapter: nil.         filelog := LogFile named: (Directory imageDir / 'log' / 'router.log') asFile addTimeStamp asVmPathName.         filelog maxLevel: 13.         log adapters add: filelog.         "log adapters add: (Transcript)."         nil     ];     yourself.

There are 4 stanzas in this example: commentBlock:, dispatcherConfigBlock:, authServicesBlock:, and logBlock. 

Also in the standard config file, the authServicesBlock: configures in 2 authentication domains: Local, the developers back door; and Test User Database, a simple self contained user/password/privileges database.

There is also a commentBlock: stanza that does nothing and is useful for commenting out old configurations and putting in inline string comments.