aMule Forum

English => aMule Help => Topic started by: Magui on January 22, 2008, 06:08:59 AM

Title: having trouble with "bind address" in amule
Post by: Magui on January 22, 2008, 06:08:59 AM
I was wondering if somebody here could explain to me how the "Bind Address" option in amule is supposed to work.  I'm experimenting with it, and according to the packets coming from amule, it doesn't seem to affect the source address at all in amule's packets. 

What's kind of annoying is that amule ignores this IP address when starting an upload or a download with a queued peer.  In other words, if I'm downloading a file, and I wait in someone else's queue, and then I begin downloading from them, amule ignores the IP address in the "Bind Address", and uses the normal (default) IP address instead.  Similar thing happens when I'm uploading to someone who is waiting in queue, and when the upload begins, amule again ignores whatever I put in for "Bind Address".  Quick explanation:  my default IP address is associated with my eth1 interface, which is the default.  I'm trying to get amule to use the ppp0 interface.  The IP address associated with ppp0 is what I'm using in the "Bind Address" box.  This set-up works very well in Azureus, and I can get high ID (green arrow) when connecting to both ed2k and Kad using ppp0.  But I keep having trouble with uploads/downloads that start after some queueing.

A quick search in this forum showed me that other people in the past have had trouble using "Bind Address" in amule.  Maybe this feature is still somewhat incomplete in amule?  If so, I would appreciate it if anybody in here would give me some tips on some alternative ways to accomplish what I'm doing, maybe with iptables or some other way.  I've spent time looking through the file amule.conf, but I don't see any other way of doing this.

Or, maybe someone can tell me how uploads and downloads start up after queueing?  If I knew more about what's involved here, I might be able to come up with some rules in iptables to stop amule from misbehaving.

Anyway, I don't know what else to try, so I would appreciate any kind of reply. 

Thanks.

edit:  I just noticed that amule does the same thing when I first start it up, and it tries to find the old sources for files that I'm downloading.  It starts TCP connections with these old sources, but it uses the default IP address, not the address that I have put in "Bind Address".
Title: Re: having trouble with "bind address" in amule
Post by: Xaignar on January 22, 2008, 02:08:11 PM
1) What version of aMule are you using?
And 2) can you check if aMule has correctly bound the ports? (try running 'netstat -npltu|grep amule')
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 22, 2008, 04:22:50 PM
1) What version of aMule are you using?
Yeah, I forgot to mention this.  It's a CVS version, dated from 3 Sept. 2007.

Quote
And 2) can you check if aMule has correctly bound the ports? (try running 'netstat -npltu|grep amule')
Code: [Select]
$ sudo netstat -npltu|grep amule
tcp        0      0 83.233.183.45:44976     0.0.0.0:*               LISTEN      21058/amule     
udp        0      0 83.233.183.45:44977     0.0.0.0:*                           21058/amule     
udp        0      0 83.233.183.45:44979     0.0.0.0:*                           21058/amule     

The IP 83.233.183.45 is the IP for ppp0.  That's what I have set for "Bind Address" in amule. 
When amule ignores this, it uses the IP 192.168.0.2, which belongs to eth1.  The port numbers shown
here look OK, I think.  The only one I haven't specified myself is the 2nd udp port, 44979.  I'm not exactly sure
what that port is for, but I have no trouble running Kad, and I don't see any obvious trouble with
finding sources (I've had trouble finding them in the past when Kad is 'firewalled' or won't connect for
some reason).
Title: Re: having trouble with "bind address" in amule
Post by: Xaignar on January 22, 2008, 05:23:04 PM
Ok, thanks for the information.

Out of curiosity, do all connections to other clients use the wrong interface, or only some of them? The reason why I ask is that, AFAICS, the problem is that we fail to specify the interface when initiating connections to new clients, but that shouldn't be a problem when accepting inbound connections.
Title: Re: having trouble with "bind address" in amule
Post by: Xaignar on January 22, 2008, 05:38:59 PM
In any case, I've committed a fix that should fix this problem.
You can try tomorrows snapshot, or try applying this patch:

Code: [Select]
Index: src/EMSocket.cpp
===================================================================
--- src/EMSocket.cpp    (revision 7997)
+++ src/EMSocket.cpp    (working copy)
@@ -34,7 +34,9 @@
 #include "GetTickCount.h"
 #include "UploadBandwidthThrottler.h"
 #include "Logger.h"
+#include "Preferences.h"

+
 const uint32 MAX_SIZE = 2000000;

 IMPLEMENT_DYNAMIC_CLASS(CEMSocket, CEncryptedStreamSocket)
@@ -42,6 +44,19 @@
 CEMSocket::CEMSocket(const CProxyData *ProxyData)
        : CEncryptedStreamSocket(wxSOCKET_NOWAIT, ProxyData)
 {
+       // If an interface has been specified,
+       // then we need to bind to it.
+       if (thePrefs::GetAddress().IsEmpty() == false) {
+               amuleIPV4Address host;
+
+               // No need to warn here, in case of failure to
+               // assign the hostname. That is already done
+               // in amule.cpp when starting ...
+               if (host.Hostname(thePrefs::GetAddress())) {
+                       SetLocal(host);
+               }
+       }
+
        byConnected = ES_NOTCONNECTED;
        m_uTimeOut = CONNECTION_TIMEOUT; // default timeout for ed2k sockets

Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 23, 2008, 04:46:49 AM
Ok, thanks for the information.

Out of curiosity, do all connections to other clients use the wrong interface, or only some of them? The reason why I ask is that, AFAICS, the problem is that we fail to specify the interface when initiating connections to new clients, but that shouldn't be a problem when accepting inbound connections.
Only some of them.

From what I can see, it only happens when amule is dealing with a queue.  When my amule client enters another client's queue, to wait for the download, my client uses the wrong interface.  Similarly, after restarting amule, and my client re-establishes a connection with a previously known source for a download, it again uses the wrong interface.  Same thing when I'm uploading.  When another client comes out of queue, and begins downloading from me, this also happens on the wrong interface.

But there are several inbound clients that always connect through the correct interface.  These are the clients that, after I first launch amule, start downloading from me with no queueing.

I agree with what you're saying, that amule appears to only be misbehaving when it initiates contact.  I know very little about what amule is doing, but the packet-captures I'd done all seemed to indicate this.  I spent some time looking for a way in iptables to more strictly control the way amule initiates connections, but had no luck.  In any case, I thought it best to keep such a big assumption about amule's behavior to myself:).
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 23, 2008, 04:50:46 AM
In any case, I've committed a fix that should fix this problem.
You can try tomorrows snapshot, or try applying this patch:
[snip]

I'll give it a try! 

I'm not really a programmer, so I probably won't bother to edit the source-code and re-compile myself.  But I'll get the snap-shot and I'll post back here and let you know what happens.
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 24, 2008, 06:16:32 AM
Well, no luck.

amule is showing much of the same behavior that it did before. 

But this time I let it run longer (for about an hour), and I noticed a few things in the amule traffic that might also have been happening with the other snapshot (I'm not really sure).

1) When I start up amule, my client still always uses the wrong interface, eth1, to contact previously-known sources for my current downloads.  What I noticed this time around is that, when it does this, it does not use the ports that I've specified for amule in preferences (TCP=44976, UDP=44977, as shown above).   Actually, I don't see any pattern to the ports that it is using here.  They seem randomly chosen.  But I always see a SYN packet go out from my client to these sources, as soon as amule starts up.

1) The majority of amule clients that are downloading from me are using the right interface, ppp0.  About 10-15% of these clients, at any time, are using the wrong interface.  From what I can see, it doesn't matter if these clients have been queued, or are just immediately beginning to download from me when I start up amule.  For these clients using the wrong interface, just as in #1, my client is using random ports to communicate with them.  As for the clients that are using the right interface, all of them are using the correct ports.

This is all I can figure out from looking over packet-capture data.  But I cannot see a pattern in which clients are using the right interface, and the clients using the wrong one.  I looked for obvious things:  name and version of remote client software, remote port number, type of file being downloaded, server being used by remote client, etc.  I don't know, maybe if I spend a few hours doing this, I might notice something, but I'm not sure.

By the way, this is what I'm running now:
aMule SVN Snapshot
 Wed Jan 23 07:01:57 CET 2008
Title: Re: having trouble with "bind address" in amule
Post by: Kry on January 24, 2008, 08:48:26 AM
Outgoing connections never use the preferences ports - those are for incoming connections.
Title: Re: having trouble with "bind address" in amule
Post by: Xaignar on January 24, 2008, 01:09:53 PM
Outgoing connections never use the preferences ports - those are for incoming connections.

Seems a bit odd to only apply it to one way, IMO.
Title: Re: having trouble with "bind address" in amule
Post by: phoenix on January 24, 2008, 01:58:07 PM
Hi Magui,

Well, no luck.

amule is showing much of the same behavior that it did before. 

But this time I let it run longer (for about an hour), and I noticed a few things in the amule traffic that might also have been happening with the other snapshot (I'm not really sure).

1) When I start up amule, my client still always uses the wrong interface, eth1, to contact previously-known sources for my current downloads.  What I noticed this time around is that, when it does this, it does not use the ports that I've specified for amule in preferences (TCP=44976, UDP=44977, as shown above).   Actually, I don't see any pattern to the ports that it is using here.  They seem randomly chosen.  But I always see a SYN packet go out from my client to these sources, as soon as amule starts up.

The bind interface is for incomming connections. In a normal situation, it should be "0.0.0.0", which means "any interface will do". If you put some address here, then you can limit the interface that is able to accept a connection.

If aMule or any other program starts a connections, then it is up to the kernel to look at the routing tables to choose the right outgoing interface. Messing with that is possible, though subtle. Those connections you see using the wrong interface have probably been started by aMule itself. For some reason the kernel has choosen this interface. Take a look at the routing table to understand what is going on, or post it here.

1) The majority of amule clients that are downloading from me are using the right interface, ppp0.  About 10-15% of these clients, at any time, are using the wrong interface.  From what I can see, it doesn't matter if these clients have been queued, or are just immediately beginning to download from me when I start up amule.  For these clients using the wrong interface, just as in #1, my client is using random ports to communicate with them.  As for the clients that are using the right interface, all of them are using the correct ports.
What you describe seems perfectly normal to me. If you start the connection, you will use a random port number in the interface that the kernel chooses. If you receive and accecpt a connection, then you will use the bind interface and the port number specified.

This is all I can figure out from looking over packet-capture data.  But I cannot see a pattern in which clients are using the right interface, and the clients using the wrong one.  I looked for obvious things:  name and version of remote client software, remote port number, type of file being downloaded, server being used by remote client, etc.  I don't know, maybe if I spend a few hours doing this, I might notice something, but I'm not sure.
Try to figure out which machine has initiated the connection, yours or the other one. That must be the difference.

Cheers!
Title: Re: having trouble with "bind address" in amule
Post by: Xaignar on January 24, 2008, 02:33:05 PM
If aMule or any other program starts a connections, then it is up to the kernel to look at the routing tables to choose the right outgoing interface. Messing with that is possible, though subtle. Those connections you see using the wrong interface have probably been started by aMule itself. For some reason the kernel has choosen this interface. Take a look at the routing table to understand what is going on, or post it here.

Hmm, the wx-docs does suggest that it's possible to specify the local address before connecting:
http://www.wxwidgets.org/manuals/2.8/wx_wxsocketbase.html#wxsocketbasesetlocal
Title: Re: having trouble with "bind address" in amule
Post by: phoenix on January 25, 2008, 04:24:39 AM
Xaignar,

I see, the documentation for wxSocketBase::SetLocal() says that for a wxSocketClient, bind() will be called before connect(), and this indeed should set the IP address and port. Normally, one does not call bind() before connect() because one doesn't care about the outgoing IP/Port that will be used, the kernel takes care of it.

I didn't know about wxSocketBase::SetLocal(), and I totally agree that your patch should have fixed the matter that Magui is reporting.
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 25, 2008, 05:54:00 AM
Outgoing connections never use the preferences ports - those are for incoming connections.
Yeah, there's something I never mentioned.  Among the iptables rules that I have set up, there are two that I use for outgoing connections.
Code: [Select]
$ sudo iptables -t nat -A POSTROUTING -p tcp --source 83.233.181.199 -j SNAT --to 83.233.181.199:44976
$ sudo iptables -t nat -A POSTROUTING -p udp --source 83.233.181.199 -j SNAT --to 83.233.181.199:44977

I don't remember exactly what I was thinking when I decided to use these rules.  I was just fumbling around, trying to get this set-up right for Azureus, and I think my reasoning went like, "If I force Azureus to only initiate connections from a certain IP and a certain port, then all replies from other clients will come to that IP and port."

This kind of assumption seems to work well enough in Azureus.  I thought it would work in amule too.  I guess the problem is because of what phoenix says:  that the "Bind address" feature is not meant to be used for outgoing connections.

The bind interface is for incomming connections. In a normal situation, it should be "0.0.0.0", which means "any interface will do". If you put some address here, then you can limit the interface that is able to accept a connection.
I must say, it surprised me when I read this from you.  I just assumed that it did more than that.  I mean, I thought amule would accept only packets that have the bind address as a destination, and would set the bind address as the source for all packets that it generates.  I guess, from what you're saying, amule only does the first part.  Well, some of the iptables rules that I had set were based on this wrong assumption.

Quote
If aMule or any other program starts a connections, then it is up to the kernel to look at the routing tables to choose the right outgoing interface. Messing with that is possible, though subtle. Those connections you see using the wrong interface have probably been started by aMule itself. For some reason the kernel has choosen this interface. Take a look at the routing table to understand what is going on, or post it here.
Yeah, I do believe that these problematic connections are all out-going.  But in Azureus, the routing I have set up already works exactly the way I want, so I'm a bit reluctant to mess with them any more.  I've pasted below the routing tables that I'm using.

Quote
What you describe seems perfectly normal to me. If you start the connection, you will use a random port number in the interface that the kernel chooses. If you receive and accecpt a connection, then you will use the bind interface and the port number specified.

Try to figure out which machine has initiated the connection, yours or the other one. That must be the difference.
Sorry about this, but my wording was wrong in my post.  What I meant was that I was seeing clients begin downloads from me after spending some time in queue.  Most of these clients would download on ppp0, but some would download on the wrong interface, on eth1.  For the clients that download on eth1, I could not see anything they have in common.  I was looking for some cause, some reason, why amule ignores the bind address for these clients, and initiates connections with them on the wrong interface, using some random port that completely ignores the port that I set using the iptables rules that I mentioned above.  I think you already gave the answer to this question.  amule will not use the bind address for outgoing connections, and I do believe that these trouble-some connections are all out-going.  Same thing happens when my amule client contacts previously-known sources for files that I am downloading.

I'm not sure what else to try now.  Xaignar has already applied a patch that I was hoping to fix this, but it looks like there's still a hole in my routing or iptables set-up somewhere.  I'll probably run amule a few more times, download more SVN snap-shots, examine closely these clients that keep showing up on the wrong interface, etc.

Here is the routing table I'm using at the moment:
Code: [Select]
$ sudo route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
83.233.181.2    192.168.0.1     255.255.255.255 UGH   0      0        0 eth1
83.233.181.2    0.0.0.0         255.255.255.255 UH    0      0        0 ppp0
192.168.0.0     0.0.0.0         255.255.255.0   U     0      0        0 eth1
0.0.0.0         192.168.0.1     0.0.0.0         UG    0      0        0 eth1
The first line is one that I added.  It just sets an outgoing route to the Internet for packets that are going out through the ppp0 interface.
The second line is added by pppd (I think) as soon as the ppp0 interface is established.
The last 2 lines are just default.  They're always there.

I also have created another routing table, specifically for the ppp0 interface.  It looks like this:
Code: [Select]
$ sudo ip route show table vpn
83.233.181.2 dev ppp0  scope link  src 83.233.181.199
default via 83.233.181.2 dev ppp0

And, just for completeness' sake,
Code: [Select]
$ sudo ifconfig
eth1      Link encap:Ethernet  HWaddr 00:a0:cc:a2:9c:ab 
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::2a0:ccff:fea2:9cab/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:18044484 errors:0 dropped:0 overruns:0 frame:0
          TX packets:24706410 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1569668379 (1.4 GiB)  TX bytes:2007729161 (1.8 GiB)
          Interrupt:11 Base address:0x6000

lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:235896 errors:0 dropped:0 overruns:0 frame:0
          TX packets:235896 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:32111883 (30.6 MiB)  TX bytes:32111883 (30.6 MiB)

ppp0      Link encap:Point-to-Point Protocol 
          inet addr:83.233.181.199  P-t-P:83.233.181.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1400  Metric:1
          RX packets:2250098 errors:0 dropped:0 overruns:0 frame:0
          TX packets:3194497 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:114763113 (109.4 MiB)  TX bytes:3708930705 (3.4 GiB)


Since this post is already becoming ridiculously long, here's my iptables set-up:
Code: [Select]
$ sudo iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
MARK       all  --  83.233.181.199       anywhere            MARK set 0x1
MARK       tcp  --  anywhere             anywhere            multiport ports 6543,4232,4242,4321,4661,4662,5000 MARK set 0x1

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         


$ sudo iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             83.233.181.199      to:83.233.181.199:44976
DNAT       udp  --  anywhere             83.233.181.199      to:83.233.181.199:44977
DNAT       tcp  --  anywhere             anywhere            multiport sports 6543,4232,4242,4321,4661,4662,5000 to:83.233.181.199:44976
DNAT       udp  --  anywhere             anywhere            multiport sports 6543,4232,4242,4321,4661,4662,5000 to:83.233.181.199:44977

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       tcp  --  83.233.181.199       anywhere            to:83.233.181.199:44976
SNAT       udp  --  83.233.181.199       anywhere            to:83.233.181.199:44977
SNAT       tcp  --  anywhere             anywhere            multiport dports 6543,4232,4242,4321,4661,4662,5000 to:83.233.181.199:44976
SNAT       udp  --  anywhere             anywhere            multiport dports 6543,4232,4242,4321,4661,4662,5000 to:83.233.181.199:44977

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
Note:  about the "MARK" targets in the mangle table, I have another rule that forces all packets marked with '1' into the ppp0 routing table.   I'm talking about the second rule displayed below.
Code: [Select]
$ sudo ip rule show
0:      from all lookup local
32765:  from all fwmark 0x1 lookup vpn
32766:  from all lookup main
32767:  from all lookup default
Title: Re: having trouble with "bind address" in amule
Post by: phoenix on January 26, 2008, 11:29:41 AM
The bind interface is for incomming connections. In a normal situation, it should be "0.0.0.0", which means "any interface will do". If you put some address here, then you can limit the interface that is able to accept a connection.
I must say, it surprised me when I read this from you.  I just assumed that it did more than that.  I mean, I thought amule would accept only packets that have the bind address as a destination, and would set the bind address as the source for all packets that it generates.  I guess, from what you're saying, amule only does the first part.  Well, some of the iptables rules that I had set were based on this wrong assumption.
Since Xaignar's patch aMule sets the address for outgoing connections too.

I am not sure your routing table / NAT will work, it looks a complicated setup. What exactly are you trying to do? Make aMule use only ppp0, while the other programs use eth1? Or make incomming packets go through a different interface from the outgoing packets?
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 26, 2008, 10:50:56 PM
Since Xaignar's patch aMule sets the address for outgoing connections too.
edit:   I forgot to reply to this.  One thing that hasn't changed is that when I start up amule, and it establishes connections with some previously-known sources for some files that I have in my download list, it ignores the bind address, and just uses the default interface, eth1.  I also see that a few clients downloading from me, once they come out of the queue, will also use eth1 for these downloads.  The majority of clients downloading from me are using ppp0, but a few are not.  Of these few, I can't see any pattern among them that would lead to them using eth1.  I think these are all out-going connections.  So I think I have a hole somewhere, but I have no idea where it is.  One thing I haven't tried yet is to actually start a new download, and see how that goes.  I get so caught up in watching the packet-capture data that I keep forgetting to try this.  I'm curious about what will happen, so I wil give it a try later. 

This is what I'm using now:

aMule SVN Snapshot:
 Thu Jan 24 07:01:57 CET 2008

Quote
I am not sure your routing table / NAT will work, it looks a complicated setup. What exactly are you trying to do? Make aMule use only ppp0, while the other programs use eth1? Or make incomming packets go through a different interface from the outgoing packets?
Yeah, it does look a bit complicated.  I mostly copied the routing set-up from this page:  http://lartc.org/howto/lartc.rpdb.multiple-links.html (http://lartc.org/howto/lartc.rpdb.multiple-links.html)
The iptables stuff I cobbled together myself by trial and error, while I was trying to get Azureus to work with this set-up.  There's a really great sketch of how the various tables in iptables work together here:  http://iptables-tutorial.frozentux.net/chunkyhtml/c962.html (http://iptables-tutorial.frozentux.net/chunkyhtml/c962.html) (scroll down to the bottom of the page).  I used this sketch as a guide in putting the iptables rules together.

Your first guess was right.  I want amule (and Azureus too, when I'm using it) to use only ppp0, while all my other network traffic uses the default routing/interface, through eth1.  As things are right now, Azureus works just fine with this set-up.  I'm running it right now, actually.  Azureus has a bind-address feature that I must use for this to work.  I assumed that the bind-address in amule worked exactly the same way.

One other thing is that, I have some rules in the mangle and the nat tables that match on several source/destination ports (6543,4232,4242,4321,4661,4662,5000).  These rules have nothing to do with Azureus.  They are for amule only, and those ports are supposed to be the listening ports for several of the edk2k servers in my server-list.  I added these rules because at one point, I was having trouble getting high-ID with all ed2k servers.  All of them kept telling me that my connection was "firewalled", and gave me a lowID.  With these rules in place, I get a high-ID every time I connect, and amule shows that I'm connected to the ed2k server through the correct interface, ppp0.

Phoenix, I appreciate that you took the time to look my long post over.  Now that you understand what I'm trying to do, if you know of a simpler way to do this (to get amule to stop using the default interface, and use some other interface of my choice), I would gladly try it out.  I just didn't see any other way of doing this.  And, besides, I already got this set-up to work for Azureus, and I thought it would be really straight-forward to use it for amule too.  I don't actually know what I'm doing, I'm not a networking guru, or anything.  I'm just trying to get amule to behave in a certain way, that's all.

Right now, I'm thinking of adding yet another rule to the mangle table, using the "owner" module in iptables, with the "userID" match.  I'm hoping that maybe this match will allow me to use a username match.  So, I would create a new user account on my machine called "amule", and then run amule as this user, and also do something similar to the following:
Code: [Select]
$ sudo iptables -t mangle -A OUTPUT --match owner --uid-owner amule -j MARK --set-mark 1
What this rule should do is add a mark "1" to all packets generated by the user "amule", which should then force the packets into ppp0.  I have no idea if such a rule is possible.  If it's possible, I have no idea if it will work.  But after spending time looking through the manpage for iptables, I don't have a better idea.  I'll do some more reading about this later.
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 27, 2008, 03:48:16 AM
I tried downloading a file in amule, to see what would happen.  I ended up downloading it from two sources.  Mixed results:  I downloaded from one source in ppp0, and from the other source in eth1.

I'm grasping at straws here, but I thought I'd bring this up anyway.  From the way amule/emule work, I understand that Kad uses UDP and is really supposed to provide a decentralized (server-less) way of finding sources for files.  All downloading/uploading still happens using TCP.  Is it possible that, when my client acquires a source through UDP, and then initiates a TCP connection with this source, that it ignores the bind address in this case?  Or does it still strictly follow Xaignar's patch, to always check for a bind-address before initiating any connection?

If this question is stupid, I apologize.  Like I said, I'm grasping at straws.  I know my client is misbehaving sometimes in these outgoing connections (the majority of connections continue to use ppp0).  I'm just struggling to find some cause that is triggering this misbehavior (I assume it's not just random).
Title: Re: having trouble with "bind address" in amule
Post by: phoenix on January 27, 2008, 02:22:40 PM
Magui,

I don't think you are doing anything wrong. But messing with NAT and routing tables is tricky.

In principle, we should have closed all the possibilities, but we can deduce from your results that there is something escaping.

You could do some tests. First, disable all the other sockets and test one network at a time. See if there is a situation where you don't get mixed sources.

We have the listening socket bound to an interface, so it is unlikely that these connections are incomming. The other possibility is that somewhere in the code aMule still uses an unbound socket to connect. Could you use wireshark to follow one of these connections since its begining to be sure of who initiated it? Also, if you can disable obfuscation, maybe wireshark is able to dissect ed2k and give us some more information.

Another thing, make sure that NAT is not fooling you somehow. Use only the strict necessary rules for your setup.
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 28, 2008, 04:37:36 AM
Magui,

I don't think you are doing anything wrong. But messing with NAT and routing tables is tricky.
Yeah, I have to agree with you here.  The iptables stuff is mostly stuff I guessed at and adjusted and re-adjusted until I got azureus to work.  But I was pretty lost on how to do the routing until I came upon the one webpage that explained how to set up multiple routes

Quote
In principle, we should have closed all the possibilities, but we can deduce from your results that there is something escaping.
Yeah, I think of it as a "hole".

Quote
You could do some tests. First, disable all the other sockets and test one network at a time. See if there is a situation where you don't get mixed sources.
I didn't understand what you meant by "disable all other sockets", but after reading "test one network at a time", I decided to try running amule with the UDP port disabled and Kad also disabled.

Quote
We have the listening socket bound to an interface, so it is unlikely that these connections are incomming. The other possibility is that somewhere in the code aMule still uses an unbound socket to connect. Could you use wireshark to follow one of these connections since its begining to be sure of who initiated it? Also, if you can disable obfuscation, maybe wireshark is able to dissect ed2k and give us some more information.
Yeah, I've been running with obfuscation disabled while I try to sort this out.  And it also appears to me that I am having no problems with incoming connections.  This mix-up with the interfaces seems to only happen with outgoing connections.

Anyway, I did notice something interesting a few minutes ago.

One client connected to my client (it sent a syn packet to my client) on the ppp0 interface, on the correct port, 44976.  A few TCP packets went back and forth, and then this connection was closed (I think this client entered my queue at this time).  About eight minutes later, my client sent a syn packet to this client, using the eth1 interface and port 55503 (just a random port, I guess).  This TCP exchange went much longer.  When I checked in amule, I was able to match the IP of this client in wireshark with the IP of a client in amule that had just come out of queue, and had begun downloading from me.  I noticed that this client was one of the first few to come out of queue, but two or three clients had come out of queue before it, and had also begun downloading.  I'm guessing they were downloading in pppo, because the packet-capture showed no downloading activity on eth1, aside from this client, and another one that I describe next.

I looked in the packet-capture for another pattern like this, and found the same thing happened with another client, at about the same time.  This other client also sent a syn packet to my client on ppp0, port 44976.  A short TCP exchange followed, and then was closed.  Nearly 10 minutes later, my client sent a syn packet to this other client using eth1, port 40980.  This TCP exchange went on until it ended with a bunch of "TCP Retransmission" packets.  Seeing this, I remembered that in amule, one of the first clients to come out of queue had begun downloading from me, and almost immediately disappeared.  Connection went bad, I guess.

All this happened after running amule for about a half-hour.  I don't have time to do much more of this right now, but I'll try come back to this tomorrow and let amule run longer and see if this happens again.  Probably also try downloading a file too, and see what happens.  The reason I noticed this today is that I set wireshark to capture all network traffic, not just traffic on eth1 (as I did previously).

Based just on this, it appears as if amule handles the bind-address differently when initiating connections with some clients in queue.  I had suspected something like this in the past few days, but I never could find anything about these clients that would cause this misbehavior in my client, while others just start downloading in pppo.  I'll have to look more closely at the queued clients that start downloading on ppp0, and see if that reveals anything.

Also, I couldn't get any more useful information about the problem of using eth1 on previously-known sources for some of my ongoing downloads.  The packet-capture only showed that, as soon as I connect to an ed2k server in amule, my client uses eth1 to send out syn packets to several IPs (the source-clients), and this initiates TCP connections with them, and my client gets into their download queues.  But I already knew this, so nothing new there.

Quote
Another thing, make sure that NAT is not fooling you somehow. Use only the strict necessary rules for your setup.
I'm not quite sure what you mean by NAT fooling me.  I think the nat rules that I have created in iptables are doing just what I want, and my previous testing indicates that packets tend to get lost without them.

By the way, I'm running:
 aMule SVN Snapshot:
 Sat Jan 26 07:01:58 CET 2008

I'll stop downloading these snap-shots for now:).  Like I said, I'll try to find time to do more of this tomorrow, and probably also start writing down the IPs of these clients.  When a few of them come out of queue at about the same time, and you look back through the packet-capture later, it can be a bit difficult to reconstruct which client was doing what and when.
Title: Re: having trouble with "bind address" in amule
Post by: phoenix on January 29, 2008, 02:42:05 AM
Magui,

Thank you very much for your time, you have given us a lot of information indeed. I hope we can find out the hole now. If you find something new, please do tell us.

Cheers!
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 29, 2008, 04:41:34 AM
I just wanted to add a few things.  I spent some more time running amule, tracking closely all clients that entered my queue for downloading.  Nearly all of them (6 or 7 clients, in about 45 minutes running amule) showed the behavior that I noted in my previous post.  They connect to me on pppo, get in queue, and then I connect to them on eth1, and I begin uploading to them.  One did not; this client actually downloaded from me on ppp0.  I looked at the packet-capture and saw that this client actually initiated the connection for beginning the download, so this was actually an incoming connection.  I can't really explain this; it's just what the packet-capture and amule both show.  This one client connected to me on ppp0, got into my queue, and then connected to me again a few minutes later on ppp0, to begin downloading.

I also tried downloading a file.  I ended up downloading it from 3 sources in total, all on pppo.  For one of the sources, I initiated the download connection.  The packet-capture actually shows a syn packet going from my client to this source.  For the other two sources, they initiated the download connection with me.  I got into the queues of a few other sources too.  For each of these sources, an outgoing connection from me used eth1.  Incoming connections from them used ppp0.

In summary:  incoming connections in amule always use ppp0 (the bind-address), and outgoing connections mostly use eth1 and occasionally use ppp0.

This is starting to get a little confusing to me.  Without knowing more about amule's code, I can't really figure out what amule is doing at all times, and how it decides when to use ppp0 or eth1.  I hope this additional information is less confusing to you.

Magui,

Thank you very much for your time, you have given us a lot of information indeed. I hope we can find out the hole now. If you find something new, please do tell us.

Cheers!
Actually, if you do manage to find something and even fix it, you'll be dong me a big favor.  I'm just glad that somebody else took the time to read my posts.  I'm willing to do this again, so if you want me to try another long packet-capture, or if you want me to save the packet-capture so you can look at it, let me know.
Title: Re: having trouble with "bind address" in amule
Post by: Xaignar on January 29, 2008, 04:19:12 PM
BTW Magui, what have you set the value of the "Bind address" setting to?
Title: Re: having trouble with "bind address" in amule
Post by: Magui on January 29, 2008, 04:35:09 PM
BTW Magui, what have you set the value of the "Bind address" setting to?
Well, it changes from time to time, because the connection gets broken.

Anyway, this is the output of 'ifconfig' at the moment on my machine
Code: [Select]
$ sudo ifconfig
eth1      Link encap:Ethernet  HWaddr 00:a0:cc:a2:9c:ab 
          inet addr:192.168.0.2  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::2a0:ccff:fea2:9cab/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:35163054 errors:0 dropped:0 overruns:0 frame:0
          TX packets:45673018 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:442312180 (421.8 MiB)  TX bytes:1773990012 (1.6 GiB)
          Interrupt:11 Base address:0x6000

lo        Link encap:Local Loopback 
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:658541 errors:0 dropped:0 overruns:0 frame:0
          TX packets:658541 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:169548348 (161.6 MiB)  TX bytes:169548348 (161.6 MiB)

ppp0      Link encap:Point-to-Point Protocol 
          inet addr:83.233.181.69  P-t-P:83.233.181.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1400  Metric:1
          RX packets:20363 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18390 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:10852368 (10.3 MiB)  TX bytes:8938926 (8.5 MiB)

The IP address that I use for "Bind Address" in amule is the same as the IP in the 'inet addr' field under the information for ppp0.  Right now, I have amule's bind-address set as 83.233.181.69.  When my ppp connection goes down (happens once every few days), and I re-connect, this IP usually changes, and I have to re-do the iptables set-up and change the bind-address in amule too.
Title: Re: having trouble with "bind address" in amule
Post by: rpsmith on March 09, 2008, 07:32:37 PM
Hi folks.  Was anyone able to solve this problem and get both incoming and outgoing connections bound to the user-specified bind address?

Here's another possibility for why it might not be working: maybe the wxSocketBase::SetLocal function is broken somehow?
Title: Re: having trouble with "bind address" in amule
Post by: rpsmith on March 11, 2008, 05:09:09 AM
I just thought of something.  This might be why bind() is not working the way we expect.  Bind assigns the source address of the IP packets coming from the socket.  It doesn't specify which interface card the computer uses to send the packet.  The computer normally routes packets by destination, so the computer can choose to send the packet out of the wrong interface even after the socket is "bound".

The way to solve this problem would be to use source-based (policy-based) routing.  This would make the computer route the packet to the proper NIC based on the source address that has been assigned by the socket bind() call, which is the behavior we are looking for.  A couple commands to iproute2 should do it, I think.  Similar to the commands described here:

http://www.linuxjournal.com/article/7291