Skip to main content

Secure Pipe is suddenly closed

7 replies [Last post]
t0bis
Offline
Joined: 2007-01-25

Could you give me some info about the secure pipe mechanics?
I create secure pipe, compose messsage to send but before sending my output pipe is closed. I don't understand algorithm of the state machine in NonBlockingOutputPipe.run(). It closes my pipe in workerState.PENDINGMIGRATE == workerstate state.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
drrsatzteil
Offline
Joined: 2007-03-23

Hi,

Thanks for this Code tra. Sorry, but i'm still a bit confused how this is supposed to work. Could you please post a piece of code how these RestoSecurePeers are created? I'm especially interested in how they establish their secure RestoPeerGroup cause i don't really get it from the spare documentation at jxta.org how to do this. Most of it is just too old i guess.

This certificate you load is one that is actually used by all the RestoPeers in the RestoPeerGroup? Sorry for these questions but i'm trying to understand how this wohle secure-group thing works but i just can't find a real explanation of what is happening here. Does anyone know some other good tutorials oder code-examples?

thanks a lot,
Thomas

t0bis
Offline
Joined: 2007-01-25

sample code:

PipeAdvertisement pout_adv = (PipeAdvertisement) AdvertisementFactory.newAdvertisement(PipeAdvertisement.getAdvertisementType());
pout_adv.setName("poutName");
pout_adv.setDescription("pout name descr");
pout_adv.setPipeID(MY_PIPE_ID);
pout_adv.setType(PipeService.UnicastSecureType);

OutputPipe outp = pipes.createOutputPipe(pout_adv, 60000);

Message msg = new Message();
byte[] data = new byte[] {1,2,3,4,5,6,7,8,9,0};
ByteArrayMessageElement element = new ByteArrayMessageElement("user_data", MimeMediaType.XMLUTF8, data, 0, data.length, null);
msg.addMessageElement(element);

// -> here pipe has been closed
outp.send(msg);

Thread.sleep(2000);

outp.close();

tra
Offline
Joined: 2003-06-16

Did you initialize the peer certificate before creating the pipe. Both ends
need to have the other end certificates.

B.

steviebe
Offline
Joined: 2007-02-12

Guys,

I'm having this same problem.

Tra can you clarify how you swap the certificates at each end?

How do you communicate this information without the output pipe?

tra
Offline
Joined: 2003-06-16

> Guys,
>
> I'm having this same problem.
>
> Tra can you clarify how you swap the certificates at
> each end?

Here is a sample modified example from the "JXTA in a Nutshell" book. The
code is not optimum, but it shows you a way to swap certficates before
creating a secure pipe

Hth,

B.

import java.io.*;
import java.util.Enumeration;
import java.util.Vector;
import java.util.Iterator;
import java.util.Arrays;
import java.net.*;

import net.jxta.peergroup.PeerGroup;
import net.jxta.exception.PeerGroupException;
import net.jxta.document.AdvertisementFactory;
import net.jxta.document.Advertisement;
import net.jxta.document.StructuredDocument;
import net.jxta.document.Element;
import net.jxta.document.StructuredDocumentFactory;
import net.jxta.document.MimeMediaType;
import net.jxta.discovery.DiscoveryService;
import net.jxta.pipe.PipeService;
import net.jxta.pipe.InputPipe;
import net.jxta.pipe.PipeID;
import net.jxta.pipe.OutputPipe;
import net.jxta.endpoint.Message;
import net.jxta.endpoint.StringMessageElement;
import net.jxta.protocol.PipeAdvertisement;
import net.jxta.protocol.PeerGroupAdvertisement;
import net.jxta.id.IDFactory;
import net.jxta.platform.NetworkConfigurator;
import net.jxta.rendezvous.RendezVousService;
import net.jxta.rendezvous.RendezvousEvent;
import net.jxta.rendezvous.RendezvousListener;
import net.jxta.credential.AuthenticationCredential;
import net.jxta.credential.Credential;
import net.jxta.impl.membership.pse.StringAuthenticator;
import net.jxta.membership.InteractiveAuthenticator;
import net.jxta.membership.MembershipService;
import net.jxta.peergroup.NetPeerGroupFactory;
import net.jxta.peergroup.PeerGroupID;
import java.security.cert.X509Certificate;
import net.jxta.impl.membership.pse.PSEMembershipService;
import net.jxta.impl.protocol.Certificate;
import java.security.KeyStoreException;
import java.security.cert.CertificateEncodingException;
import net.jxta.protocol.PeerAdvertisement;
import net.jxta.document.Attributable;
import net.jxta.id.ID;

// The HungryPeer joins the RestoNet PeerGroup and searches for
// RestoPeers. The HungryPeer then establishes a pipe connection to
// all the RestoPeers that it discovered. The HungryPeer sends
// auction requests for French fries to RestoPeers and then waits for
// auction bids from RestoPeers

public class HungryPeer {

transient NetworkManager manager; // Network manager
private PeerGroup netpg = null; // NetPeergroup
private PeerGroup restoNet = null; // Resto Peergroup

// Services within the RestoNet Peergroup
private DiscoveryService disco; // Discovery Service
private PipeService pipes; // Pipe Service
private PipeAdvertisement myAdv; // Hungry peer pipe advertisement
private InputPipe myPipe; // Input pipe to talk to hungry peer
private MimeMediaType mimeType = new MimeMediaType("text", "xml");

private int timeout = 5000; // Discovery timeout
private int timeout1 = 3000; // Discovery timeout
private int rtimeout = 5000; // Pipe Resolver Timeout
// All RestoPeers found
private Vector restoPeerAdvs = new Vector();
private Vector restoPeerPipes = new Vector();

private String myIdentity = "Bill Joy"; // Identity of this HungryPeer
private String friesRequest ="medium"; // Fries Auction request

public static void main(String args[]) {
HungryPeer myapp = new HungryPeer();
myapp.startJxta();
}

private void startJxta() {

//Discover and join (or start) the default peergroup
manager = new NetworkManager("HungrySecurePeer");
manager.start("principal1", "password1");
//Get the NetPeerGroup
netpg = manager.getNetPeerGroup();
manager.login(netpg, "principal1", "password1");
System.out.println("Peer Name " + netpg.getPeerName());

// Get Certificate in key store to create secure pipe
importCertificate();

// Discover and join the RestoNet Peergroup
try {
if (!joinRestoNet()) {
System.out.println("Sorry could not find the RestoNet Peergroup");
System.exit(2);
}
} catch (Exception e) {
System.out.println("Can't join RestoNet group");
System.exit(1);
}

// Set our HungryPeer communication pipe so RestoPeers
// can talk to us
if (!setHungryPeerPipe()) {
System.out.println(
"Aborting due to failure to create our HungryPeer pipe");
System.exit(1);
}

// Attempt to locate RestoPeers in RestoNet
discoverRestoPeers();

// Connect to RestoPeers that have been discovered
connectToRestoPeers();

// I am hungry. Send an auction request for French Fries
// to the connected RestoPeers.
sendFriesAuctionRequests();

//Process incoming bids from RestoPeers
receiveFriesBids();

// Stop
myPipe.close();
restoNet.unref();
restoNet.stopApp();
manager.stop();
}

// This method is used to discover the RestoNet Peergroup.
// If found the peer will join the peergroup
private boolean joinRestoNet() {

int count = 40; // maximum number of attempts to discover

System.out.println("Attempting to discover the RestoNet Peergroup");

// Get the Discovery service handle from the NetPeerGroup
DiscoveryService hdisco = netpg.getDiscoveryService();

// All discovered RestoNet Peers
Enumeration ae = null;

// Loop until we find the "RestoNet" Peergroup advertisement
// or we've exhausted the desired number of attempts
while (count-- > 0) {
try {
// Check if we have the advertisement in the local
// peer cache
ae = hdisco.getLocalAdvertisements(DiscoveryService.GROUP,
"Name", "RestoNet");

// If we found the RestoNet advertisement, we are done
if ((ae != null) && ae.hasMoreElements())
break;

// The RestoNet advertisement is not in the local
// cache . Send a discovery request to search for it.
hdisco.getRemoteAdvertisements(null,
DiscoveryService.GROUP, "Name", "RestoNet", 1, null);

// Wait to give peers a chance to respond
try {
Thread.sleep(timeout);
} catch (InterruptedException ie) {}
} catch (IOException e) {
// Found nothing! Move on.
}
}

// Check if we found the RestoNet advertisement
if (ae == null || !ae.hasMoreElements()) {
return false;
}

System.out.println("Found the RestoNet PeerGroup Advertisement");
// Get the advertisement
PeerGroupAdvertisement adv =
(PeerGroupAdvertisement) ae.nextElement();

try {
// Call the PeerGroup Factory to instantiate a new
// peergroup instance
restoNet = netpg.newGroup(adv);

// Get the Discovery and Pipe services to
// be used within the RestoNet Peergroup
disco = restoNet.getDiscoveryService();
pipes = restoNet.getPipeService();
} catch (Exception e) {
System.out.println("Could not create RestoPeerGroup");
return false;
}

System.out.println("The HungryPeer joined the restoNet PeerGroup");
return true;
}

// Create the HungryPeer pipe to receive bid responses
// from RestoPeers. The advertisement of this pipe is sent as part
// of the auction request for RestoPeers to respond.
private boolean setHungryPeerPipe() {
try {
// Create a pipe advertisement for our hungry peer. This
// pipe will be used within the RestoNet peergroup for other
// peers to talk to our hungry peer
myAdv = (PipeAdvertisement)
AdvertisementFactory.newAdvertisement(
PipeAdvertisement.getAdvertisementType());

// Initialize the advertisement with unique peer information
// So we can communicate
myAdv.setPipeID(IDFactory.newPipeID(restoNet.getPeerGroupID()));
myAdv.setName("restoNet:HungryPipe:" + myIdentity);

// Set the pipe type to be unicast unidrectional
myAdv.setType(PipeService.UnicastSecureType);

// Create the input pipe
myPipe = pipes.createInputPipe(myAdv);
} catch (Exception e) {
System.out.println("Could not create the HungryPeer pipe");
return false;
}
return true;
}

// Method to get certificate
public void importCertificate() {

boolean trimChain = false;
PSEMembershipService pse = (PSEMembershipService) netpg.getMembershipService();
DiscoveryService disco = netpg.getDiscoveryService();

// Get the advertisement of the Hungry peer to extract the
//certificate
Enumeration ae = null; // Holds the discovered peers
int count = 80;

System.out.println("Waiting to discover RestoSecurePeer advertisement to get certificate");
// Loop until we discover the HungryPeer peer advertisement or
// until we've exhausted the desired number of attempts
while (count-- > 0) {
try {
// search first in the peer local cache to find
// the RestoNet peergroup advertisement
ae = disco.getLocalAdvertisements(DiscoveryService.PEER,
"Name", "RestoSecurePeer");

// If we found the RestoNet advertisement we are done
if ((ae != null) && ae.hasMoreElements())
break;

// If we did not find it, we send a discovery request
disco.getRemoteAdvertisements(null,
DiscoveryService.PEER, "Name", "RestoSecurePeer", 1, null);

// Sleep to allow time for peers to respond to the
// discovery request
try {
Thread.sleep(timeout);
} catch (InterruptedException ie) {}
} catch (IOException e){
// Found nothing! Move on
}
}

if (! ae.hasMoreElements()) {
System.out.println("Could not find RestoSecurePeer advertisement, exiting");
manager.stop();
System.exit(1);
}

PeerAdvertisement pa = (PeerAdvertisement) ae.nextElement();
ID createid = pa.getPeerID();

StructuredDocument rootParams = pa.getServiceParam( PeerGroup.peerGroupClassID );

if( null == rootParams ) {
throw new IllegalArgumentException( "Peer advertisement does not contain group parameters" );
}

Enumeration eachRoot = rootParams.getChildren( "RootCert" );

if( !eachRoot.hasMoreElements() ) {
throw new IllegalArgumentException("Peer advertisement does not contain root certificate" );
}

Element root = (Element) eachRoot.nextElement();

if( root instanceof Attributable) {
// XXX 20040719 bondolo Backwards compatibility hack. Adds type so cert chain is recognized.
((Attributable)root).addAttribute( "type", Certificate.getMessageType() );
}

Certificate cert_msg = new Certificate( root );

try {
Iterator sourceChain = Arrays.asList( cert_msg.getCertificates() ).iterator();
int imported = 0;
X509Certificate aCert = (X509Certificate) sourceChain.next();

do {
if( null != pse.getPSEConfig().getTrustedCertificateID( aCert ) ) {
break;
}

pse.getPSEConfig().erase( createid );
pse.getPSEConfig().setTrustedCertificate( createid, aCert );
imported++;

// create a codat id for the next certificate in the chain.
aCert = null;
if( sourceChain.hasNext() ) {
aCert = (X509Certificate) sourceChain.next();

if( trimChain ) {
if( null != pse.getPSEConfig().getTrustedCertificateID( aCert ) ) {
// it's already in the pse, time to bail!
break;
}
}
byte [] der = aCert.getEncoded();
createid = IDFactory.newCodatID( netpg.getPeerGroupID(), new ByteArrayInputStream(der) );
}
} while( null != aCert );

System.out.println( "Imported " + imported + " certificates. " );

} catch( CertificateEncodingException failure ) {
IllegalStateException failed = new IllegalStateException( "Bad certificate" );
failed.initCause( failure );
throw failed;
} catch( KeyStoreException failure ) {
IllegalStateException failed = new IllegalStateException( "KeyStore failure while importing certificate." );
failed.initCause( failure );
throw failed;
} catch( IOException failure ) {
IllegalStateException failed = new IllegalStateException( "IO failure while importing certificate." );
failed.initCause( failure );
throw failed;
}

}

// Discover RestoPeers that have joined RestoNet.
// RestoPeers are discovered via their published pipe advertisement.
private void discoverRestoPeers() {
int found = 0; // Count of RestoPeers found
int count = 10; // Discovery retries

System.out.println("Locating RestoPeers in the RestoNet Peergroup");

// Try to find at least two RestoPeers (an arbitrary number)
// RestoPeers are found by their pipe advertisements
while (count-- >0) {
try {
// Check if we already have restaurant advertisements
// in our local peer cache
Enumeration ae =
disco.getLocalAdvertisements(DiscoveryService.ADV,
"Name", "RestoNet:RestoPipe:Chez JXTA");

// If we found some advertisements in the cache,
// add them to the list
if (ae != null && ae.hasMoreElements()) {
// Reset count and RestoPeerAdvs as we have
// just retrieved all advertisements, including
// previously cached ones
found = 0;
restoPeerAdvs.removeAllElements();
while (ae.hasMoreElements()) {
restoPeerAdvs.addElement(ae.nextElement());
++found;
}
if (found > 1)
break; // Want to find at least two
}

// Did not find enough advertisement in the cache.
// Send a remote discovery request to search for
// more RestoPeer advertisements
disco.getRemoteAdvertisements(null,
DiscoveryService.ADV,
"Name", "RestoNet:RestoPipe:Chez JXTA", 5, null);

// Give the peers a chance to respond
try {
Thread.sleep(timeout1);
} catch (InterruptedException e) {}
} catch (IOException e){
// Found nothing! Move on
}
}
// Completed RestoPeer Discovery
System.out.println("Found " + found + " RestoPeers(s)");
}

// Method to connect and open output pipes to all the
// RestoPeers that we have discovered. Each RestoPeer is
// identified by its unique RestoPeer pipe advertisement.
private void connectToRestoPeers() {
// Enumerate all the RestoPeer pipe advertisments we have discovered
// and attempt to connect a pipe which each of them
for (Enumeration en = restoPeerAdvs.elements();
en.hasMoreElements();) {

PipeAdvertisement padv = (PipeAdvertisement) en.nextElement();
try {
System.out.println(
"Attempting to connect to discovered RestoPeer");

// Create an output pipe connection to the RestoPeer
System.out.println("Connecting on pipe:" + padv.getPipeID().toString());
OutputPipe pipeOut = pipes.createOutputPipe(padv,
rtimeout);

// Check if we have a connected pipe
if (pipeOut == null) {
// Failed; go to next RestoPeer
System.out.println(
"Failure to connect to RestoPeer Pipe:" +
padv.getName());
continue;
}

// Save the output pipe
restoPeerPipes.addElement(pipeOut);
System.out.println("Connected pipe to " + padv.getName());
} catch (Exception e) {
// Error during connection go to next RestoPeer
System.out.println("RestoPeer may not be there anymore:" +
padv.getName());
continue;
}
}
}

// Send an auction request for French Fries to all the RestoPeer
// pipes we have successfully connected
private void sendFriesAuctionRequests() {
// Enumerate all the RestoPeer pipe connections we have successfully
// connected to
for (Enumeration en = restoPeerPipes.elements();
en.hasMoreElements();) {
OutputPipe op = (OutputPipe) en.nextElement();
try {
// Construct the request document
StructuredDocument request =
StructuredDocumentFactory.newStructuredDocument(mimeType,
"RestoNet:Request");

// Fill up the Fries auction request argument
Element re;
re = request.createElement("Name", myIdentity);
request.appendChild(re);
re = request.createElement("Fries", friesRequest);
request.appendChild(re);

// Create the pipe message to send
Message msg = new Message();

// Fill the first message element which is the HungryPeer
// pipe advertisement return address. We need this
// so RestoPeers can respond to us
StringMessageElement sme =
new StringMessageElement("HungryPeerPipe", myAdv.toString(), null);
msg.addMessageElement((String) null, sme);

// Fill the second message element, which is
// the fries request. Insert the document
// in the message

sme = new StringMessageElement("Request", request.toString(), null);
msg.addMessageElement((String) null, sme);

// Send the auction message to the RestoPeer
op.send(msg);
System.out.println("Sent Fries Auction Request ("
+ friesRequest + ") to connected peers");
} catch (Exception ex) {
// Error sending auction request
System.out.println(
"Failed to send auction request to RestoPeer");
}
}
}

// Receive bid requests from RestoPeers on the
// HungryPeer listening pipe
private void receiveFriesBids() {

boolean received = false;

// Continue until we get all answers
while (! received) {
Message msg = null; // Pipe message received
String price = null; // Fries price bid
String brand = null; // RestoPeer name which offers the bid
String specials = null; // Specials offer bid
InputStream ip = null; // Input stream to read message element
StructuredDocument bid = null; //Bid document received

try {
// Wait for a bid message to arrive from a RestoPeer
// Will block until a message arrive
msg = myPipe.waitForMessage();

// Check if the message is valid
if (msg == null) {
if (Thread.interrupted()) {
// We have been asked to stop
System.out.println(
"Abort Receiving bid loop interrupted");
myPipe.close(); // Close the Pipe
return;
}
}
} catch (Exception ex) {
// Error in receiving message
myPipe.close();
System.out.println("Abort Receiving Error receiving bids");
return;
}

// We got a message from a RestoPeer.
// Extract and display infomation about the bid received.
try {
// Extract the Bid document from the message
ip = msg.getMessageElement(null, "Bid").getStream();
bid = StructuredDocumentFactory.newStructuredDocument(
mimeType, ip);

// Parse the document to extract bid information
Enumeration enumn = bid.getChildren();
while (enumn.hasMoreElements()) {
Element element = (Element) enumn.nextElement();
String attr = (String) element.getKey();
String value = (String) element.getValue();
if (attr.equals("Price")) {
price = value;
continue;
}
if (attr.equals("Brand")) {
brand = value;
continue;
}
if (attr.equals("Specials")) {
specials = value;
continue;
}
}

// We got a valid bid. Print it.
System.out.println("Received Fries Bid from RestoPeers (" +
brand + ") at a Price ($" + price +
") \nRestoPeers Special (" + specials + ")");
received = true;
} catch (Exception e) {
// Broken content
System.out.println("Error extracting bid from the message");
continue;
}
}
}

/**
* A simple and re-usable exmaple of starting and stopping a JXTA platform
*
* @author Mohamed Abdelaziz (hamada)
* @created December 17, 2005
*/

public class NetworkManager implements RendezvousListener {

private PeerGroup netPeerGroup = null;
private boolean started = false;
private boolean stopped = false;
private RendezVousService rendezvous;
private final Object connectLock = new Object();
private String instanceName = "NA";
private final File home = new File(System.getProperty("JXTA_HOME", ".cache"));

/**
* A simple and re-usable exmaple of starting and stopping a JXTA platform
*
* @param instanceName Node name
*/
public NetworkManager(String instanceName) {
this.instanceName = instanceName;
}

/**
* Creates and starts the JXTA NetPeerGroup using a platform configuration
* template. This class also registers a listener for rendezvous events
*
* @param principal principal used the generate the self signed peer root cert
* @param password the root cert password
*/
public synchronized void start(String principal, String password) {
if (started) {
return;
}
try {
File instanceHome = new File(home, instanceName);
NetworkConfigurator config = new NetworkConfigurator();
config.setHome(instanceHome);
if (!config.exists()) {
config.setPeerID(IDFactory.newPeerID(PeerGroupID.defaultNetPeerGroupID));
config.setName(instanceName);
config.setDescription("Created by Network Manager");
config.setMode(NetworkConfigurator.EDGE_NODE);
config.setPrincipal(principal);
config.setPassword(password);
try {
config.addSeedRendezvous(new URI("http://129.146.55.53:9700"));
config.addSeedRelay(new URI("http://129.146.55.53:9700"));
//config.addRdvSeedingURI(new URI("http://rdv.jxtahosts.net/cgi-bin/rendezvous.cgi?2"));
//config.addRelaySeedingURI(new URI("http://rdv.jxtahosts.net/cgi-bin/relays.cgi?2"));
} catch (java.net.URISyntaxException use) {
use.printStackTrace();
}
try {
config.save();
} catch (IOException io) {
io.printStackTrace();
}
} else {
try {
File pc = new File(config.getHome(), "PlatformConfig");
config.load(pc.toURI());
} catch (Exception ex) {
ex.printStackTrace();
}
}
// create, and Start the default jxta NetPeerGroup
NetPeerGroupFactory factory = new NetPeerGroupFactory(config.getPlatformConfig(), instanceHome.toURI());
netPeerGroup = factory.getInterface();
System.out.println("Node PeerID :" + netPeerGroup.getPeerID().getUniqueValue().toString());
rendezvous = netPeerGroup.getRendezVousService();
rendezvous.addListener(this);
started = true;
} catch (PeerGroupException e) {
// could not instantiate the group, print the stack and exit
System.out.println("fatal error : group creation failure");
e.printStackTrace();
System.exit(1);
}
}

/**
* Establishes group credential. This is a required step when planning to
* to utilize TLS messegers or secure pipes
*
* @param group peer group to establish credentials in
* @param principal the principal
* @param password pass word
*/
public void login(PeerGroup group, String principal, String password) {
try {
StringAuthenticator auth = null;
MembershipService membership = group.getMembershipService();
Credential cred = membership.getDefaultCredential();
if (cred == null) {
AuthenticationCredential authCred = new AuthenticationCredential(group, "StringAuthentication", null);
try {
auth = (StringAuthenticator) membership.apply(authCred);
} catch (Exception failed) {
failed.printStackTrace();
}

if (auth != null) {
auth.setAuth1_KeyStorePassword(password.toCharArray());
auth.setAuth2Identity(group.getPeerID());
auth.setAuth3_IdentityPassword(principal.toCharArray());
if (auth.isReadyForJoin()) {
membership.join(auth);
}
}
}

cred = membership.getDefaultCredential();
if (null == cred) {
AuthenticationCredential authCred = new AuthenticationCredential(group, "InteractiveAuthentication", null);
InteractiveAuthenticator iAuth = (InteractiveAuthenticator) membership.apply(authCred);
if (iAuth.interact() && iAuth.isReadyForJoin()) {
membership.join(iAuth);
}
}
} catch (Throwable e) {
// make sure output buffering doesn't wreck console display.
System.err.println("Uncaught Throwable caught by 'main':");
e.printStackTrace();
System.exit(1);
} finally {
System.err.flush();
System.out.flush();
}
}

/**
* Stops and unrefrences the NetPeerGroup
*/
public synchronized void stop() {
if (stopped && !started) {
return;
}
rendezvous.removeListener(this);
netPeerGroup.stopApp();
netPeerGroup.unref();
netPeerGroup = null;
stopped = true;
}

/**
* Gets the netPeerGroup object
*
* @return The netPeerGroup value
*/
public PeerGroup getNetPeerGroup() {
return netPeerGroup;
}

/**
* Blocks if not connected to a rendezvous, or
* until a connection to rendezvous node occurs
*
* @param timeout timeout in milliseconds
*/
public void waitForRendezvousConncection(long timeout) {
if (!rendezvous.isConnectedToRendezVous() || !rendezvous.isRendezVous()) {
System.out.println("Waiting for Rendezvous Connection");
try {
if (!rendezvous.isConnectedToRendezVous()) {
synchronized (connectLock) {
connectLock.wait(timeout);
}
}
System.out.println("Connected to Rendezvous");
} catch (InterruptedException e) {
System.out.println("thread interrupted");
}
}
}

/**
* rendezvousEvent the rendezvous event
*
* @param event rendezvousEvent
*/
public void rendezvousEvent(RendezvousEvent event) {
if (event.getType() == RendezvousEvent.RDVCONNECT ||
event.getType() == RendezvousEvent.RDVRECONNECT ||
event.getType() == RendezvousEvent.BECAMERDV) {
switch (event.getType()) {
case RendezvousEvent.RDVCONNECT:
System.out.println("Connected to rendezvous peer :" + event.getPeerID());
break;
case RendezvousEvent.RDVRECONNECT:
System.out.println("Reconnected to rendezvous peer :" + event.getPeerID());
break;
case RendezvousEvent.BECAMERDV:
System.out.println("Became a Rendezvous");
break;
}
synchronized (connectLock) {
connectLock.notify();
}
}
}
}
}

>
> How do you communicate this information without the
> output pipe?

tra
Offline
Joined: 2003-06-16

Sorry, I just found out that the forum was updated and is now reformating entries :-( I
looking to get a fix for allowing people to post code on the Forum

B.

tra
Offline
Joined: 2003-06-16

Looks the formating is now working :-)