Log4Net: IP parsing bug when used with framework .NET 2.0

Update (2008/08/21):

As stated by SergeS in his comment, the solution I provide below (while working)  should not be used any more. Instead, replace your src/Appender/UdpAppender.cs file with the one found here:

https://svn.apache.org/viewvc/logging/log4net/trunk/src/Appender/UdpAppender.cs?revision=506603

I’m using log4net 1.2.10 for a few month now and couldn’t ever get rid of it. Today I was playing with the udp appender: I was trying to have my application send logs via udp to Log4NetViewer… and nothing happened. After having enabled the log4net debug mode (1), I could see there was something wrong with the way log4net parsed my IP (2):

log4nelog4net:ERROR [UdpAppender] Unable to send logging event to remote host ::1 on port 1234.
System.Net.Sockets.SocketException: Une adresse incompatible avec le protocole demandé a été utilisée
à System.Net.Sockets.Socket.SendTo(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint remoteEP)
à System.Net.Sockets.UdpClient.Send(Byte[] dgram, Int32 bytes, IPEndPoint endPoint)
à log4net.Appender.UdpAppender.Append(LoggingEvent loggingEvent)

log4net was transforming my “192.168.0.2” parameter IP into ::1, and the problem took place in the method IPAddressConverter.ConvertFrom() (the file is located under log4net-1.2.10\src\Util\TypeConverters\IPAddressConverter.cs).
The problem is that when compiled with .NET 2.0, the original code is returning the first IP address associated with the host (host itself returned by a dns lookup):

IPHostEntry host = Dns.GetHostEntry(str);
if (host != null &&
    host.AddressList != null &&
    host.AddressList.Length > 0 &&
    host.AddressList[0] != null)
{ 
    return host.AddressList[0];
}

When inspecting the content of this address list with the debugger I got:

+ [0] {::1} System.Net.IPAddress
+ [1] {192.168.0.2} System.Net.IPAddress
+ [2] {192.168.206.1} System.Net.IPAddress
+ [3] {192.168.114.1} System.Net.IPAddress

So, with the existing code, the address ::1 is selected… and the UdpAppender throws an exception 😦 To avoid this:
first I added this property to IPAddressConverter:

public bool IsIPv6Supported { get { return false; } }

note that I’m not networking aware, and thus this may be replaced by some code able to detect wether or not IP v6 is supported…
then I replaced “
return host.AddressList[0];” with:

foreach (IPAddress address in host.AddressList)
{
    if ((address.AddressFamily ==
        System.Net.Sockets.AddressFamily.InterNetworkV6) &&
        !IsIPv6Supported) 
        continue;
                                
    return address;
}
This way, I return the first IPv4 address instead of the first address.Hope this helps 

(1) to do so, just add the following xml to your app.config:

<appSettings>
<add key=log4net.Internal.Debug value=true/>
</
appSettings>

(2) aproximatively translated from French into English: The used address is incompatible with the requested protocol

PS: if you want to compile the log4net visual studio project provided with the distribution, you have to apply these guidelines: http://logging.apache.org/log4net/release/building.html#vsnet-2005

Advertisements