Snow Leopard – Cannot connect to MySQL 4.1+ using old authentication

Snow Leopard upgraded php to 5.3, this means that passwords have to be changed – usually via SET password FOR ‘user’@'host’ = PASSWORD( ‘password’ ). This is fine, and can be verified by SELECT LENGTH( password ), user FROM mysql.user. The result should be 41.

I had inadvertently enabled old_password=1 in /etc/my.cnf, this caused both PASSWORD and OLD_PASSWORD to return the same value. To fix this, simply comment out the old_password=1 line in my.cnf and restart mysqld.

Hopefully this saves someone a few dozen google searches.

Maximum memory available to AIR Applications in Windows – Why AIR/Flash needs to be 64-bit

Let’s be honest, at some point in time we’ve all tried to load a stupendously large number of images into flash just to see what would happen. Unsurprisingly, Flash will crash. Precisely when it will crash however seems to be enshrouded in mystery. The reason why there doesn’t appear to be any direct Adobe documentation on the issue is that it’s not so much a Flash issue as an OS issue.

The maximum memory available to AIR applications is limited to 2gb (in windows) by the 32 bit nature of the Adobe AIR runtime. In windows this means that the maximum memory available will be around 2 gigabytes. (In tests my application consistently died at around 1.8gb). This limit is independent of the OS architecture – it makes no difference if you’re running Windows 32 bit or Windows 64 bit.

According to an MSDN article (http://msdn.microsoft.com/en-us/library/aa366778%28VS.85%29.aspx) the IMAGE_FILE_LARGE_ADDRESS_AWARE should allow 32 bit applications to access up to 4 gb of memory, I think it’s safe to assume that this option is not enabled in the Windows AIR runtime.

If Adobe is serious about AIR competing on an equal footing with native applications it is vital that these memory issues are resolved. Whilst AIR 2.0 seems to be a step in the right direction and I understand that using a runtime environment will never be the same as building a native app, I’d still love to see a 64 bit version of AIR.

(This article only pertains to the Windows AIR runtime, I haven’t tested Mac OS X or Linux. There is a 64 bit version of AIR for linux in closed beta.)

Contextual scope handlers in Red5 (appLeave vs roomLeave, appStop vs roomStop, etc)

The issue is

In Red5 different scope handlers triggered by universal events (such as a client disconnecting) will be invoked depending on whether or not the universal event applies to the application scope (the root scope) or a child scope. For instance, if a client disconnects from the application, this will call the appStop, appLeave and appDisconnect handlers. By disconnecting from the application scope the client is also disconnecting from all child scopes (ie: rooms), however these handlers are not called.

A little bit confusing

Of itself, that behaviour’s not too difficult to grasp and I certainly haven’t had anywhere close to enough exposure to the design premise behind red5 to comment on it. Having said that, there are a couple of things which I find a little bit confusing:

  1. The difference between the disconnect and leave handlers is not immediately obvious. It appears that both these handlers are called from the disconnect method on the Scope class (org.red5.server.Scope). My best guess at the moment is that the duplicitous methods have been left in for backwards compatibility or cohesion with FMS.
  2. It seems like the only time the room handlers will be called is if a client is directly connected to a child scope and then wishes to regress to a higher scope. ie: the client connects directly to a room and then drops back to the application scope. In my case the reverse is usually true; the client connects to a lobby and then proceeds to connect to a room (child scope). Connecting to a child scope however is treated by a red5 as a completely new connection, triggering the appConnect handler and resulting in a new client id being assigned to the connection.

I’ve only been using Red5 for a couple of weeks now, so it’s likely a lot of the confusion is my own fault. The code I’m using to connect to a child scope on the server-side was provided by flashmonkey at http://www.flashmonkey.org/?p=341:

public void changeScope() {
IConnection connection = Red5.getConnectionLocal(); IScope currentScope = connection.getScope(); boolean success = currentScope.createChildScope("ChildScope"); if (success) {
IScope newScope = currentScope.getScope("ChildScope"); newScope.connect(connection);
}
}

Red5 Application Directory Structure

For future reference, (and for the benefit of the worldwide interwebs), I thought I’d share the directory structure I use for my Red5 applications; it’s fairly standard but there’s not an overwhelming amount of documentation out there. (It’s based on the examples at http://code.google.com/p/red5/source/browse/java/example/trunk/).

Source folder

-> src
-> libs
-> www
-> WEB-INF
-> classes
-> logback-APPLICATION_NAME.xml
-> lib -> red5-web.properties -> red5-web.xml -> web.xml
  • The src folder builds to www/WEB-INF/classes
  • www is symbolically linked to webapps/APPLICATION_NAME
  • APPLICATION_NAME should be replaced with the name of your application

red5-web.properties

webapp.contextPath=/APPLICATION_NAME
webapp.virtualHosts=localhost, 127.0.0.1

red5-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>

<bean id="placeholderConfig">
<property name="location" value="/WEB-INF/red5-web.properties" />
</bean>

<bean id="web.context"
autowire="byType" />

<bean id="web.scope"
init-method="register">
<property name="server" ref="red5.server" />
<property name="parent" ref="global.scope" />
<property name="context" ref="web.context" />
<property name="handler" ref="web.handler" />
<property name="contextPath" value="${webapp.contextPath}" />
<property name="virtualHosts" value="${webapp.virtualHosts}" />
</bean>

<bean id="web.handler" singleton="true" />
</beans>

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">

<display-name>APPLICATION_NAME</display-name>

<context-param>
<param-name>webAppRootKey</param-name>
<param-value>/APPLICATION_NAME</param-value>
</context-param>

<listener>
<listener-class>org.red5.logging.ContextLoggingListener</listener-class>
</listener>

<filter>
<filter-name>LoggerContextFilter</filter-name>
<filter-class>org.red5.logging.LoggerContextFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>LoggerContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- remove the following servlet tags if you want to disable remoting for this application -->
<servlet>
<servlet-name>gateway</servlet-name>
<servlet-class>
org.red5.server.net.servlet.AMFGatewayServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>gateway</servlet-name>
<url-pattern>/gateway</url-pattern>
</servlet-mapping>

<security-constraint>
<web-resource-collection>
<web-resource-name>Forbidden</web-resource-name>
<url-pattern>/streams/*</url-pattern>
</web-resource-collection>
<auth-constraint/>
</security-constraint>

</web-app>

logback-APPLICATION_NAME.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<contextName>APPLICATION_NAME</contextName>
<jmxConfigurator contextName="APPLICATION_NAME" />
<appender name="APPLICATION_NAME">
<File>log/APPLICATION_NAME.log</File>
<Append>false</Append>
<Encoding>UTF-8</Encoding>
<BufferedIO>false</BufferedIO>
<ImmediateFlush>true</ImmediateFlush>
<layout>
<Pattern>
%date [%thread] %-5level %logger{35} - %msg%n
</Pattern>
</layout>
</appender>
<root>
<appender-ref ref="APPLICATION_NAME" />
</root>
<logger name="PACKAGE">
<level value="DEBUG" />
</logger>
</configuration>

Monitoring Bandwidth Usage with DD-WRT, Chillispot and FreeRadius

Recording bandwidth used by wifi clients sounds like a relatively simple task. $90 and far too many hours later I can assure you that for a person without much network experience it can be deceptively challenging.

This article is a quick guide describing how to configure DD-WRT, Chillispot and Freeradius for the specific use case of mac-address freeradius authentication and accounting. It also briefly touches on web-based admin solutions. A radius server handles authorisation and accounting (ie: counting of bandwidth used by wifi users). The Chillispot instance within DD-WRT funnels all wifi clients through this authorisation and periodically, (if so configured), dispatches accounting packets to the radius server.

The Purpose

The purpose of my configuration is to restrict access to my wireless network and monitor the bandwidth consumed by authorised users. Consequently, the setup which this article describes is not orientated towards a hotspot, as all authentication is performed based on mac addresses.

The main focus of this post is on configuring a Chillispot instance within a router running DD-WRT. For information about setting up free radius check out the following sites:

  • http://wiki.freeradius.org/
  • http://www.howtoforge.com/authentication-authorization-and-accounting-with-freeradius-and-mysql-backend-and-webbased-management-with-daloradius

The Pieces

  1. A router running DD-WRT
  2. A configured free radius server

DD-WRT and Chillispot

Full versions of DD-WRT come bundled with Chillispot, however getting Chillispot and free radius using mac-address authorisation to play nicely can be a little bit tricky. The main thing to remember is that DHCP servers within DD-WRT should be disabled as Chillispot contains its own DHCP server. It may be possible to get the various instances to exist harmoniously but the simplest solution for me was just disable them. To configure DD-WRT:

  1. Disable the DHCP server under setup, untick all checkboxes relating to DNSMasq.
  2. Disable DNSMasq under the Services tab.
  3. If you haven’t already, you should probably set some form of security for your wireless network.
  4. Enable Chillispot under Services->Hotspot.

Configuring Chillispot

The following image details my Chillispot setup:

Chillispot configuration in DDWRT

Chillispot configuration in DDWRT

Most of the parameters are relatively self explanatory. More information can be found here: http://www.dd-wrt.com/wiki/index.php/Chillispot. The parameters of note are:

  • The UAM secret is irrelevant for mac-address based authentication. (It is passed by Chillispot to a login script. Mac-based authentication does not require a login script).
  • The shared key should correspond with the secret set in your freeradius client configuration (located at /etc/raddb/clients.conf for me).
  • UAM allowed is a comma-delimited list of sites unauthenticated users can access.
  • Setting MACAuth to true causes Chillispot to make an authentication request against free radius when a user joins the wireless network, where User =%MAC_ADDRESS%, Pass = Password. %MAC_ADDRESS% is replaced with the user’s mac address, Pass, by default, is literally the string “Password”.
  • The additional Chillispot option of macpasswd changes the default password used for mac-address authentication, in my case to “sushi”.

Configuring a Radius user account

Rad-check attributes:

  • username = %MAC_ADDRESS%
  • User-Password := “Password” (or the value set by macpasswd)

Rad-reply (accounting) attributes:

  • Acct-Interim-Interval := 300
  • Idle-Timeout := 600

The above attributes cause Chillispot to send updates about bandwidth usage to the radius server every 5 minutes. If a user has been idle for 10 minutes their session is terminated.

That’s all you need! You should have a (mostly) functioning setup at this point in time, the rest of the article is focused on web-based admin tools.

Web-based Administration

Free Radius:

  • Dalo Radius allows you to create user accounts from a web-based interface for your radius server. It requires that your radius server is configured via MySQL. http://daloradius.com