[sip-comm-dev] Re: [Fmj-devel] FMJ uses the remote (target) port number to open a local socket (port)


#1

I apologize for my ignorance of using multicast sockets, but I have a hunch that the problem lies in the fact that FMJ specifies a port in the constructor of its unicast sockets. When sending a datagram packet, the port is specified, so I'm wondering if the port is not needed when constructing the multicast socket, and serves only to do what you say is the problem: open that port locally.

I could be totally off base here, but you could try the following patch to FMJ which changes this.

Looking at the javadoc, it appears that a local socket will still be opened, but it will be "any available port on the local host machine".

Ken

### Eclipse Workspace Patch 1.0
#P fmj
Index: src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java

···

===================================================================
RCS file: /cvsroot/fmj/fmj/src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java,v
retrieving revision 1.7
diff -u -r1.7 RTPSocketAdapter.java
--- src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java 15 Oct 2007 23:01:05 -0000 1.7
+++ src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java 9 Jun 2008 23:14:15 -0000
@@ -119,8 +119,8 @@
             // If the address is multicast, create multicast sockets and joing
             // groups etc
             if (addr.isMulticastAddress()) {
- dataSock = new EncryptedRTPSocket(null, port);
- ctrlSock = new EncryptedRTPSocket(null, port + 1);
+ dataSock = new EncryptedRTPSocket(null, EncryptedRTPSocket.isRTP(port));
+ ctrlSock = new EncryptedRTPSocket(null, EncryptedRTPSocket.isRTP(port + 1));
                 //((MulticastSocket) dataSock).setInterface(laddr);
                 ((MulticastSocket) dataSock).joinGroup(addr);
                 ((MulticastSocket) dataSock).setTimeToLive(ttl);
@@ -133,8 +133,8 @@
              // If the address is unicast, create unicast sockets
             else {
- dataSock = new EncryptedRTPSocket(null, port);
- ctrlSock = new EncryptedRTPSocket(null, port + 1);
+ dataSock = new EncryptedRTPSocket(null, EncryptedRTPSocket.isRTP(port));
+ ctrlSock = new EncryptedRTPSocket(null, EncryptedRTPSocket.isRTP(port + 1));
             }
         } catch (SocketException e) {
             throw new IOException(e.getMessage());
Index: src.rtp/memetic/crypto/EncryptedRTPSocket.java

RCS file: /cvsroot/fmj/fmj/src.rtp/memetic/crypto/EncryptedRTPSocket.java,v
retrieving revision 1.3
diff -u -r1.3 EncryptedRTPSocket.java
--- src.rtp/memetic/crypto/EncryptedRTPSocket.java 26 Oct 2007 21:43:20 -0000 1.3
+++ src.rtp/memetic/crypto/EncryptedRTPSocket.java 9 Jun 2008 23:14:15 -0000
@@ -57,6 +57,16 @@
     // True if this is an RTP socket
     private boolean isRTP = true;
+ public EncryptedRTPSocket(RTPCrypt crypt, boolean isRTP) throws IOException {
+ super();
+ this.crypt = crypt;
+ this.isRTP = isRTP;
+ }
+ + public static boolean isRTP(int port)
+ { return ((port % 2) == 0);
+ }
+ /**
      * Creates a new EncryptedRTPSocket bound to the specified port
      *

Werner Dittmann wrote:

A few days ago I downloaded a CVS version of FMJ to build test programs,
a RTP client and a RTP Server that already work using JMF. Trying to do the
same with FMJ resulted in problems. Here the code snippet how I created
the RTPManager and initialize it:

...
SessionAddress sa = new SessionAddress(ia, 5002);
SessionAddress target = new SessionAddress(ia, 5004);
try {

     mgr = RTPManager.newInstance();

     mgr.initialize(sa);

     mgr.addSessionListener(this);
     mgr.addReceiveStreamListener(this);

     mgr.addTarget(target);
} catch (Exception e) {
     System.err.println("Cannot create the RTP Session: " + e.getMessage());
}

...

This is the normal way to setup RTP and add a target. Well, FMJ also opens the
*target port* number on the *local* system - which is wrong because this is a port
on the *remote system* that may not be available on the local system.
This behaviour may cause spurious problems on the local system. The problem is
located in FMJ's classes RTPSocketAdapter and EncryptedRTPSocket.

FMJ must open the port number of the session address given in initialize(...) only.
The target address is written into the DatagramPacket only and this DatagramPacket
is sent using the open port given during initialize(...).

Hope this finding helps to fix this in FMJ.

Regards,
Werner

PS: when using an own connector, mgr.initialize() is called with the connector
and setting the target at this connector works well - communication was established
(tested with my modifed and bug fixed SRTP connector). This also proves that the
connector implementation of FMJ's RTPSocketAdapter is buggy.

Werner

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Fmj-devel mailing list
Fmj-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fmj-devel

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#2

Hi,

Just to add a warning to this: if you open a DatagramSocket listening port p and then send to port p, most firewalls (not all) will allow the return traffic to come back to port p. If you send on port p and receive on port q, this will not be the case - the firewall doesn't recognise the return path (I don't know why this is the case given that you specify both the source and destination ports in UDP, but there you go - maybe its because the source port is optional?).

I would advise that you create a constructor that allows you to choose if you want to bind any old port and another that allows you to fix the local port to one of your choosing. I think this is what you have done below, but then I never have been good at reading diffs!

Note that the main difference between multicast and unicast is that with multicast, you are going to need to listen and send on the same port, whereas with unicast, you don't necessarily have to (except for the above).

Andrew :slight_smile:

···

---------------------------------------------------------

  Andrew G D Rowley
  Senior Development Officer

  Research Computing Services
  The University of Manchester
  Kilburn Building, Oxford Road
  Manchester, M13 9PL

  t : +44 (0) 161 275 0685
  e : Andrew.Rowley@manchester.ac.uk
  w : www.manchester.ac.uk/researchcomputing

---------------------------------------------------------

-----Original Message-----

From: fmj-devel-bounces@lists.sourceforge.net [mailto:fmj-devel-bounces@lists.sourceforge.net] On Behalf Of Ken Larson

Sent: 10 June 2008 00:20
To: Werner Dittmann
Cc: dev@sip-communicator.dev.java.net; fmj-devel@lists.sourceforge.net
Subject: Re: [Fmj-devel] FMJ uses the remote (target) port number to open a local socket (port)

I apologize for my ignorance of using multicast sockets, but I have a
hunch that the problem lies in the fact that FMJ specifies a port in the
constructor of its unicast sockets. When sending a datagram packet, the
port is specified, so I'm wondering if the port is not needed when
constructing the multicast socket, and serves only to do what you say is
the problem: open that port locally.

I could be totally off base here, but you could try the following patch
to FMJ which changes this.

Looking at the javadoc, it appears that a local socket will still be
opened, but it will be "any available port on the local host machine".

Ken

### Eclipse Workspace Patch 1.0
#P fmj
Index: src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java

RCS file:
/cvsroot/fmj/fmj/src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java,v
retrieving revision 1.7
diff -u -r1.7 RTPSocketAdapter.java
--- src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java 15 Oct 2007
23:01:05 -0000 1.7
+++ src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java 9 Jun 2008
23:14:15 -0000
@@ -119,8 +119,8 @@
             // If the address is multicast, create multicast sockets
and joing
             // groups etc
             if (addr.isMulticastAddress()) {
- dataSock = new EncryptedRTPSocket(null, port);
- ctrlSock = new EncryptedRTPSocket(null, port + 1);
+ dataSock = new EncryptedRTPSocket(null,
EncryptedRTPSocket.isRTP(port));
+ ctrlSock = new EncryptedRTPSocket(null,
EncryptedRTPSocket.isRTP(port + 1));
                 //((MulticastSocket) dataSock).setInterface(laddr);
                 ((MulticastSocket) dataSock).joinGroup(addr);
                 ((MulticastSocket) dataSock).setTimeToLive(ttl);
@@ -133,8 +133,8 @@

             // If the address is unicast, create unicast sockets
             else {
- dataSock = new EncryptedRTPSocket(null, port);
- ctrlSock = new EncryptedRTPSocket(null, port + 1);
+ dataSock = new EncryptedRTPSocket(null,
EncryptedRTPSocket.isRTP(port));
+ ctrlSock = new EncryptedRTPSocket(null,
EncryptedRTPSocket.isRTP(port + 1));
             }
         } catch (SocketException e) {
             throw new IOException(e.getMessage());
Index: src.rtp/memetic/crypto/EncryptedRTPSocket.java

RCS file: /cvsroot/fmj/fmj/src.rtp/memetic/crypto/EncryptedRTPSocket.java,v
retrieving revision 1.3
diff -u -r1.3 EncryptedRTPSocket.java
--- src.rtp/memetic/crypto/EncryptedRTPSocket.java 26 Oct 2007
21:43:20 -0000 1.3
+++ src.rtp/memetic/crypto/EncryptedRTPSocket.java 9 Jun 2008
23:14:15 -0000
@@ -57,6 +57,16 @@
     // True if this is an RTP socket
     private boolean isRTP = true;

+ public EncryptedRTPSocket(RTPCrypt crypt, boolean isRTP) throws
IOException {
+ super();
+ this.crypt = crypt;
+ this.isRTP = isRTP;
+ }
+
+ public static boolean isRTP(int port)
+ { return ((port % 2) == 0);
+ }
+
     /**
      * Creates a new EncryptedRTPSocket bound to the specified port
      *

Werner Dittmann wrote:

A few days ago I downloaded a CVS version of FMJ to build test programs,
a RTP client and a RTP Server that already work using JMF. Trying to do the
same with FMJ resulted in problems. Here the code snippet how I created
the RTPManager and initialize it:

...
SessionAddress sa = new SessionAddress(ia, 5002);
SessionAddress target = new SessionAddress(ia, 5004);
try {

     mgr = RTPManager.newInstance();

     mgr.initialize(sa);

     mgr.addSessionListener(this);
     mgr.addReceiveStreamListener(this);

     mgr.addTarget(target);
} catch (Exception e) {
     System.err.println("Cannot create the RTP Session: " + e.getMessage());
}

...

This is the normal way to setup RTP and add a target. Well, FMJ also opens the
*target port* number on the *local* system - which is wrong because this is a port
on the *remote system* that may not be available on the local system.
This behaviour may cause spurious problems on the local system. The problem is
located in FMJ's classes RTPSocketAdapter and EncryptedRTPSocket.

FMJ must open the port number of the session address given in initialize(...) only.
The target address is written into the DatagramPacket only and this DatagramPacket
is sent using the open port given during initialize(...).

Hope this finding helps to fix this in FMJ.

Regards,
Werner

PS: when using an own connector, mgr.initialize() is called with the connector
and setting the target at this connector works well - communication was established
(tested with my modifed and bug fixed SRTP connector). This also proves that the
connector implementation of FMJ's RTPSocketAdapter is buggy.

Werner

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Fmj-devel mailing list
Fmj-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fmj-devel

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Fmj-devel mailing list
Fmj-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fmj-devel

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Fmj-devel mailing list
Fmj-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fmj-devel


#3

Hi Ken,

A multicast socket is just a "normal" socket using a special IP address which is a multicast one. Thus, you have to manage an UDP port the same way for an unicast or a multicast stream.

Hope this helps,
Vincent

Ken Larson wrote:

···

I apologize for my ignorance of using multicast sockets, but I have a hunch that the problem lies in the fact that FMJ specifies a port in the constructor of its unicast sockets. When sending a datagram packet, the port is specified, so I'm wondering if the port is not needed when constructing the multicast socket, and serves only to do what you say is the problem: open that port locally.

I could be totally off base here, but you could try the following patch to FMJ which changes this.

Looking at the javadoc, it appears that a local socket will still be opened, but it will be "any available port on the local host machine".

Ken

### Eclipse Workspace Patch 1.0
#P fmj
Index: src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java

RCS file: /cvsroot/fmj/fmj/src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java,v
retrieving revision 1.7
diff -u -r1.7 RTPSocketAdapter.java
--- src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java 15 Oct 2007 23:01:05 -0000 1.7
+++ src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java 9 Jun 2008 23:14:15 -0000
@@ -119,8 +119,8 @@
            // If the address is multicast, create multicast sockets and joing
            // groups etc
            if (addr.isMulticastAddress()) {
- dataSock = new EncryptedRTPSocket(null, port);
- ctrlSock = new EncryptedRTPSocket(null, port + 1);
+ dataSock = new EncryptedRTPSocket(null, EncryptedRTPSocket.isRTP(port));
+ ctrlSock = new EncryptedRTPSocket(null, EncryptedRTPSocket.isRTP(port + 1));
                //((MulticastSocket) dataSock).setInterface(laddr);
                ((MulticastSocket) dataSock).joinGroup(addr);
                ((MulticastSocket) dataSock).setTimeToLive(ttl);
@@ -133,8 +133,8 @@

            // If the address is unicast, create unicast sockets
            else {
- dataSock = new EncryptedRTPSocket(null, port);
- ctrlSock = new EncryptedRTPSocket(null, port + 1);
+ dataSock = new EncryptedRTPSocket(null, EncryptedRTPSocket.isRTP(port));
+ ctrlSock = new EncryptedRTPSocket(null, EncryptedRTPSocket.isRTP(port + 1));
            }
        } catch (SocketException e) {
            throw new IOException(e.getMessage());
Index: src.rtp/memetic/crypto/EncryptedRTPSocket.java

RCS file: /cvsroot/fmj/fmj/src.rtp/memetic/crypto/EncryptedRTPSocket.java,v
retrieving revision 1.3
diff -u -r1.3 EncryptedRTPSocket.java
--- src.rtp/memetic/crypto/EncryptedRTPSocket.java 26 Oct 2007 21:43:20 -0000 1.3
+++ src.rtp/memetic/crypto/EncryptedRTPSocket.java 9 Jun 2008 23:14:15 -0000
@@ -57,6 +57,16 @@
    // True if this is an RTP socket
    private boolean isRTP = true;

+ public EncryptedRTPSocket(RTPCrypt crypt, boolean isRTP) throws IOException {
+ super();
+ this.crypt = crypt;
+ this.isRTP = isRTP;
+ }
+ + public static boolean isRTP(int port)
+ { return ((port % 2) == 0);
+ }
+ /**
     * Creates a new EncryptedRTPSocket bound to the specified port
     *

Werner Dittmann wrote:

A few days ago I downloaded a CVS version of FMJ to build test programs,
a RTP client and a RTP Server that already work using JMF. Trying to do the
same with FMJ resulted in problems. Here the code snippet how I created
the RTPManager and initialize it:

...
SessionAddress sa = new SessionAddress(ia, 5002);
SessionAddress target = new SessionAddress(ia, 5004);
try {

     mgr = RTPManager.newInstance();

     mgr.initialize(sa);

     mgr.addSessionListener(this);
     mgr.addReceiveStreamListener(this);

     mgr.addTarget(target);
} catch (Exception e) {
     System.err.println("Cannot create the RTP Session: " + e.getMessage());
}

...

This is the normal way to setup RTP and add a target. Well, FMJ also opens the
*target port* number on the *local* system - which is wrong because this is a port
on the *remote system* that may not be available on the local system.
This behaviour may cause spurious problems on the local system. The problem is
located in FMJ's classes RTPSocketAdapter and EncryptedRTPSocket.

FMJ must open the port number of the session address given in initialize(...) only.
The target address is written into the DatagramPacket only and this DatagramPacket
is sent using the open port given during initialize(...).

Hope this finding helps to fix this in FMJ.

Regards,
Werner

PS: when using an own connector, mgr.initialize() is called with the connector
and setting the target at this connector works well - communication was established
(tested with my modifed and bug fixed SRTP connector). This also proves that the
connector implementation of FMJ's RTPSocketAdapter is buggy.

Werner

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Fmj-devel mailing list
Fmj-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fmj-devel

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net


#4

Hi,

This is not entirely true - with all UDP connections you can usually ask the OS to allow it to be bound more than once. With unicast, this doesn't really make sense and you usually find that only one of the sockets ever receives anything. With multicast, each of the connections should receive the same traffic, no matter how many times you bind the same port. The problems come when you try to bind with unicast and then again with multicast - this tends not to work.

Andrew :slight_smile:

···

---------------------------------------------------------

  Andrew G D Rowley
  Senior Development Officer

  Research Computing Services
  The University of Manchester
  Kilburn Building, Oxford Road
  Manchester, M13 9PL

  t : +44 (0) 161 275 0685
  e : Andrew.Rowley@manchester.ac.uk
  w : www.manchester.ac.uk/researchcomputing

---------------------------------------------------------

-----Original Message-----

From: fmj-devel-bounces@lists.sourceforge.net [mailto:fmj-devel-bounces@lists.sourceforge.net] On Behalf Of Vincent Lucas

Sent: 10 June 2008 08:46
To: dev@sip-communicator.dev.java.net
Cc: fmj-devel@lists.sourceforge.net
Subject: Re: [Fmj-devel] [sip-comm-dev] Re: FMJ uses the remote (target) port number to open a local socket (port)

Hi Ken,

A multicast socket is just a "normal" socket using a special IP address
which is a multicast one. Thus, you have to manage an UDP port the same
way for an unicast or a multicast stream.

Hope this helps,
Vincent

Ken Larson wrote:

I apologize for my ignorance of using multicast sockets, but I have a
hunch that the problem lies in the fact that FMJ specifies a port in the
constructor of its unicast sockets. When sending a datagram packet, the
port is specified, so I'm wondering if the port is not needed when
constructing the multicast socket, and serves only to do what you say is
the problem: open that port locally.

I could be totally off base here, but you could try the following patch
to FMJ which changes this.

Looking at the javadoc, it appears that a local socket will still be
opened, but it will be "any available port on the local host machine".

Ken

### Eclipse Workspace Patch 1.0
#P fmj
Index: src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java

RCS file:
/cvsroot/fmj/fmj/src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java,v
retrieving revision 1.7
diff -u -r1.7 RTPSocketAdapter.java
--- src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java 15 Oct 2007
23:01:05 -0000 1.7
+++ src.rtp/net/sf/fmj/media/rtp/RTPSocketAdapter.java 9 Jun 2008
23:14:15 -0000
@@ -119,8 +119,8 @@
            // If the address is multicast, create multicast sockets and
joing
            // groups etc
            if (addr.isMulticastAddress()) {
- dataSock = new EncryptedRTPSocket(null, port);
- ctrlSock = new EncryptedRTPSocket(null, port + 1);
+ dataSock = new EncryptedRTPSocket(null,
EncryptedRTPSocket.isRTP(port));
+ ctrlSock = new EncryptedRTPSocket(null,
EncryptedRTPSocket.isRTP(port + 1));
                //((MulticastSocket) dataSock).setInterface(laddr);
                ((MulticastSocket) dataSock).joinGroup(addr);
                ((MulticastSocket) dataSock).setTimeToLive(ttl);
@@ -133,8 +133,8 @@

            // If the address is unicast, create unicast sockets
            else {
- dataSock = new EncryptedRTPSocket(null, port);
- ctrlSock = new EncryptedRTPSocket(null, port + 1);
+ dataSock = new EncryptedRTPSocket(null,
EncryptedRTPSocket.isRTP(port));
+ ctrlSock = new EncryptedRTPSocket(null,
EncryptedRTPSocket.isRTP(port + 1));
            }
        } catch (SocketException e) {
            throw new IOException(e.getMessage());
Index: src.rtp/memetic/crypto/EncryptedRTPSocket.java

RCS file: /cvsroot/fmj/fmj/src.rtp/memetic/crypto/EncryptedRTPSocket.java,v
retrieving revision 1.3
diff -u -r1.3 EncryptedRTPSocket.java
--- src.rtp/memetic/crypto/EncryptedRTPSocket.java 26 Oct 2007
21:43:20 -0000 1.3
+++ src.rtp/memetic/crypto/EncryptedRTPSocket.java 9 Jun 2008
23:14:15 -0000
@@ -57,6 +57,16 @@
    // True if this is an RTP socket
    private boolean isRTP = true;

+ public EncryptedRTPSocket(RTPCrypt crypt, boolean isRTP) throws
IOException {
+ super();
+ this.crypt = crypt;
+ this.isRTP = isRTP;
+ }
+ + public static boolean isRTP(int port)
+ { return ((port % 2) == 0);
+ }
+ /**
     * Creates a new EncryptedRTPSocket bound to the specified port
     *

Werner Dittmann wrote:

A few days ago I downloaded a CVS version of FMJ to build test programs,
a RTP client and a RTP Server that already work using JMF. Trying to
do the
same with FMJ resulted in problems. Here the code snippet how I created
the RTPManager and initialize it:

...
SessionAddress sa = new SessionAddress(ia, 5002);
SessionAddress target = new SessionAddress(ia, 5004);
try {

     mgr = RTPManager.newInstance();

     mgr.initialize(sa);

     mgr.addSessionListener(this);
     mgr.addReceiveStreamListener(this);

     mgr.addTarget(target);
} catch (Exception e) {
     System.err.println("Cannot create the RTP Session: " +
e.getMessage());
}

...

This is the normal way to setup RTP and add a target. Well, FMJ also
opens the
*target port* number on the *local* system - which is wrong because
this is a port
on the *remote system* that may not be available on the local system.
This behaviour may cause spurious problems on the local system. The
problem is
located in FMJ's classes RTPSocketAdapter and EncryptedRTPSocket.

FMJ must open the port number of the session address given in
initialize(...) only.
The target address is written into the DatagramPacket only and this
DatagramPacket
is sent using the open port given during initialize(...).

Hope this finding helps to fix this in FMJ.

Regards,
Werner

PS: when using an own connector, mgr.initialize() is called with the
connector
and setting the target at this connector works well - communication
was established
(tested with my modifed and bug fixed SRTP connector). This also
proves that the
connector implementation of FMJ's RTPSocketAdapter is buggy.

Werner

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Fmj-devel mailing list
Fmj-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fmj-devel

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@sip-communicator.dev.java.net
For additional commands, e-mail: dev-help@sip-communicator.dev.java.net

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Fmj-devel mailing list
Fmj-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fmj-devel

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Fmj-devel mailing list
Fmj-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/fmj-devel