mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-15 20:29:52 +01:00
Exchange transport properties when adding contact.
This commit is contained in:
@@ -10,17 +10,22 @@ import org.briarproject.api.crypto.CryptoComponent;
|
|||||||
import org.briarproject.api.crypto.KeyParser;
|
import org.briarproject.api.crypto.KeyParser;
|
||||||
import org.briarproject.api.crypto.SecretKey;
|
import org.briarproject.api.crypto.SecretKey;
|
||||||
import org.briarproject.api.crypto.Signature;
|
import org.briarproject.api.crypto.Signature;
|
||||||
|
import org.briarproject.api.data.BdfList;
|
||||||
import org.briarproject.api.data.BdfReader;
|
import org.briarproject.api.data.BdfReader;
|
||||||
import org.briarproject.api.data.BdfReaderFactory;
|
import org.briarproject.api.data.BdfReaderFactory;
|
||||||
import org.briarproject.api.data.BdfWriter;
|
import org.briarproject.api.data.BdfWriter;
|
||||||
import org.briarproject.api.data.BdfWriterFactory;
|
import org.briarproject.api.data.BdfWriterFactory;
|
||||||
import org.briarproject.api.db.ContactExistsException;
|
import org.briarproject.api.db.ContactExistsException;
|
||||||
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
|
import org.briarproject.api.db.Transaction;
|
||||||
import org.briarproject.api.identity.Author;
|
import org.briarproject.api.identity.Author;
|
||||||
import org.briarproject.api.identity.AuthorFactory;
|
import org.briarproject.api.identity.AuthorFactory;
|
||||||
import org.briarproject.api.identity.LocalAuthor;
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.plugins.ConnectionManager;
|
import org.briarproject.api.plugins.ConnectionManager;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
|
||||||
|
import org.briarproject.api.properties.TransportProperties;
|
||||||
|
import org.briarproject.api.properties.TransportPropertyManager;
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.transport.StreamReaderFactory;
|
import org.briarproject.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.api.transport.StreamWriterFactory;
|
import org.briarproject.api.transport.StreamWriterFactory;
|
||||||
@@ -29,13 +34,19 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
|
import static org.briarproject.api.TransportId.MAX_TRANSPORT_ID_LENGTH;
|
||||||
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
|
||||||
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
|
||||||
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
|
||||||
|
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT;
|
||||||
|
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
|
||||||
|
|
||||||
public class ContactExchangeTaskImpl extends Thread
|
public class ContactExchangeTaskImpl extends Thread
|
||||||
implements ContactExchangeTask {
|
implements ContactExchangeTask {
|
||||||
@@ -43,35 +54,40 @@ public class ContactExchangeTaskImpl extends Thread
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(ContactExchangeTaskImpl.class.getName());
|
Logger.getLogger(ContactExchangeTaskImpl.class.getName());
|
||||||
|
|
||||||
|
private final DatabaseComponent db;
|
||||||
private final AuthorFactory authorFactory;
|
private final AuthorFactory authorFactory;
|
||||||
private final BdfReaderFactory bdfReaderFactory;
|
private final BdfReaderFactory bdfReaderFactory;
|
||||||
private final BdfWriterFactory bdfWriterFactory;
|
private final BdfWriterFactory bdfWriterFactory;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final ConnectionManager connectionManager;
|
private final ConnectionManager connectionManager;
|
||||||
private final ContactManager contactManager;
|
private final ContactManager contactManager;
|
||||||
|
private final TransportPropertyManager transportPropertyManager;
|
||||||
private final CryptoComponent crypto;
|
private final CryptoComponent crypto;
|
||||||
private final StreamReaderFactory streamReaderFactory;
|
private final StreamReaderFactory streamReaderFactory;
|
||||||
private final StreamWriterFactory streamWriterFactory;
|
private final StreamWriterFactory streamWriterFactory;
|
||||||
|
|
||||||
private ContactExchangeListener listener;
|
private volatile ContactExchangeListener listener;
|
||||||
private LocalAuthor localAuthor;
|
private volatile LocalAuthor localAuthor;
|
||||||
private DuplexTransportConnection conn;
|
private volatile DuplexTransportConnection conn;
|
||||||
private TransportId transportId;
|
private volatile TransportId transportId;
|
||||||
private SecretKey masterSecret;
|
private volatile SecretKey masterSecret;
|
||||||
private boolean alice;
|
private volatile boolean alice;
|
||||||
|
|
||||||
public ContactExchangeTaskImpl(AuthorFactory authorFactory,
|
public ContactExchangeTaskImpl(DatabaseComponent db,
|
||||||
BdfReaderFactory bdfReaderFactory,
|
AuthorFactory authorFactory, BdfReaderFactory bdfReaderFactory,
|
||||||
BdfWriterFactory bdfWriterFactory, Clock clock,
|
BdfWriterFactory bdfWriterFactory, Clock clock,
|
||||||
ConnectionManager connectionManager, ContactManager contactManager,
|
ConnectionManager connectionManager, ContactManager contactManager,
|
||||||
|
TransportPropertyManager transportPropertyManager,
|
||||||
CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
|
CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
|
||||||
StreamWriterFactory streamWriterFactory) {
|
StreamWriterFactory streamWriterFactory) {
|
||||||
|
this.db = db;
|
||||||
this.authorFactory = authorFactory;
|
this.authorFactory = authorFactory;
|
||||||
this.bdfReaderFactory = bdfReaderFactory;
|
this.bdfReaderFactory = bdfReaderFactory;
|
||||||
this.bdfWriterFactory = bdfWriterFactory;
|
this.bdfWriterFactory = bdfWriterFactory;
|
||||||
this.clock = clock;
|
this.clock = clock;
|
||||||
this.connectionManager = connectionManager;
|
this.connectionManager = connectionManager;
|
||||||
this.contactManager = contactManager;
|
this.contactManager = contactManager;
|
||||||
|
this.transportPropertyManager = transportPropertyManager;
|
||||||
this.crypto = crypto;
|
this.crypto = crypto;
|
||||||
this.streamReaderFactory = streamReaderFactory;
|
this.streamReaderFactory = streamReaderFactory;
|
||||||
this.streamWriterFactory = streamWriterFactory;
|
this.streamWriterFactory = streamWriterFactory;
|
||||||
@@ -93,24 +109,12 @@ public class ContactExchangeTaskImpl extends Thread
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
// Derive the header keys for the transport streams
|
// Get the transport connection's input and output streams
|
||||||
SecretKey aliceHeaderKey = crypto.deriveHeaderKey(masterSecret, true);
|
InputStream in;
|
||||||
SecretKey bobHeaderKey = crypto.deriveHeaderKey(masterSecret, false);
|
OutputStream out;
|
||||||
BdfReader r;
|
|
||||||
BdfWriter w;
|
|
||||||
try {
|
try {
|
||||||
// Create the readers
|
in = conn.getReader().getInputStream();
|
||||||
InputStream streamReader =
|
out = conn.getWriter().getOutputStream();
|
||||||
streamReaderFactory.createInvitationStreamReader(
|
|
||||||
conn.getReader().getInputStream(),
|
|
||||||
alice ? bobHeaderKey : aliceHeaderKey);
|
|
||||||
r = bdfReaderFactory.createReader(streamReader);
|
|
||||||
// Create the writers
|
|
||||||
OutputStream streamWriter =
|
|
||||||
streamWriterFactory.createInvitationStreamWriter(
|
|
||||||
conn.getWriter().getOutputStream(),
|
|
||||||
alice ? aliceHeaderKey : bobHeaderKey);
|
|
||||||
w = bdfWriterFactory.createWriter(streamWriter);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
listener.contactExchangeFailed();
|
listener.contactExchangeFailed();
|
||||||
@@ -118,6 +122,32 @@ public class ContactExchangeTaskImpl extends Thread
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the local transport properties
|
||||||
|
Map<TransportId, TransportProperties> localProperties, remoteProperties;
|
||||||
|
try {
|
||||||
|
localProperties = transportPropertyManager.getLocalProperties();
|
||||||
|
} catch (DbException e) {
|
||||||
|
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
|
||||||
|
listener.contactExchangeFailed();
|
||||||
|
tryToClose(conn, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Derive the header keys for the transport streams
|
||||||
|
SecretKey aliceHeaderKey = crypto.deriveHeaderKey(masterSecret, true);
|
||||||
|
SecretKey bobHeaderKey = crypto.deriveHeaderKey(masterSecret, false);
|
||||||
|
|
||||||
|
// Create the readers
|
||||||
|
InputStream streamReader =
|
||||||
|
streamReaderFactory.createInvitationStreamReader(in,
|
||||||
|
alice ? bobHeaderKey : aliceHeaderKey);
|
||||||
|
BdfReader r = bdfReaderFactory.createReader(streamReader);
|
||||||
|
// Create the writers
|
||||||
|
OutputStream streamWriter =
|
||||||
|
streamWriterFactory.createInvitationStreamWriter(out,
|
||||||
|
alice ? aliceHeaderKey : bobHeaderKey);
|
||||||
|
BdfWriter w = bdfWriterFactory.createWriter(streamWriter);
|
||||||
|
|
||||||
// Derive the nonces to be signed
|
// Derive the nonces to be signed
|
||||||
byte[] aliceNonce = crypto.deriveSignatureNonce(masterSecret, true);
|
byte[] aliceNonce = crypto.deriveSignatureNonce(masterSecret, true);
|
||||||
byte[] bobNonce = crypto.deriveSignatureNonce(masterSecret, false);
|
byte[] bobNonce = crypto.deriveSignatureNonce(masterSecret, false);
|
||||||
@@ -130,13 +160,19 @@ public class ContactExchangeTaskImpl extends Thread
|
|||||||
if (alice) {
|
if (alice) {
|
||||||
sendPseudonym(w, aliceNonce);
|
sendPseudonym(w, aliceNonce);
|
||||||
sendTimestamp(w, localTimestamp);
|
sendTimestamp(w, localTimestamp);
|
||||||
|
sendTransportProperties(w, localProperties);
|
||||||
|
w.flush();
|
||||||
remoteAuthor = receivePseudonym(r, bobNonce);
|
remoteAuthor = receivePseudonym(r, bobNonce);
|
||||||
remoteTimestamp = receiveTimestamp(r);
|
remoteTimestamp = receiveTimestamp(r);
|
||||||
|
remoteProperties = receiveTransportProperties(r);
|
||||||
} else {
|
} else {
|
||||||
remoteAuthor = receivePseudonym(r, aliceNonce);
|
remoteAuthor = receivePseudonym(r, aliceNonce);
|
||||||
remoteTimestamp = receiveTimestamp(r);
|
remoteTimestamp = receiveTimestamp(r);
|
||||||
|
remoteProperties = receiveTransportProperties(r);
|
||||||
sendPseudonym(w, bobNonce);
|
sendPseudonym(w, bobNonce);
|
||||||
sendTimestamp(w, localTimestamp);
|
sendTimestamp(w, localTimestamp);
|
||||||
|
sendTransportProperties(w, localProperties);
|
||||||
|
w.flush();
|
||||||
}
|
}
|
||||||
// Close the outgoing stream and expect EOF on the incoming stream
|
// Close the outgoing stream and expect EOF on the incoming stream
|
||||||
w.close();
|
w.close();
|
||||||
@@ -159,7 +195,7 @@ public class ContactExchangeTaskImpl extends Thread
|
|||||||
try {
|
try {
|
||||||
// Add the contact
|
// Add the contact
|
||||||
ContactId contactId = addContact(remoteAuthor, masterSecret,
|
ContactId contactId = addContact(remoteAuthor, masterSecret,
|
||||||
timestamp, alice);
|
timestamp, alice, remoteProperties);
|
||||||
// Reuse the connection as a transport connection
|
// Reuse the connection as a transport connection
|
||||||
connectionManager.manageOutgoingConnection(contactId, transportId,
|
connectionManager.manageOutgoingConnection(contactId, transportId,
|
||||||
conn);
|
conn);
|
||||||
@@ -187,19 +223,22 @@ public class ContactExchangeTaskImpl extends Thread
|
|||||||
signature.update(nonce);
|
signature.update(nonce);
|
||||||
byte[] sig = signature.sign();
|
byte[] sig = signature.sign();
|
||||||
// Write the name, public key and signature
|
// Write the name, public key and signature
|
||||||
|
w.writeListStart();
|
||||||
w.writeString(localAuthor.getName());
|
w.writeString(localAuthor.getName());
|
||||||
w.writeRaw(localAuthor.getPublicKey());
|
w.writeRaw(localAuthor.getPublicKey());
|
||||||
w.writeRaw(sig);
|
w.writeRaw(sig);
|
||||||
w.flush();
|
w.writeListEnd();
|
||||||
LOG.info("Sent pseudonym");
|
LOG.info("Sent pseudonym");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Author receivePseudonym(BdfReader r, byte[] nonce)
|
private Author receivePseudonym(BdfReader r, byte[] nonce)
|
||||||
throws GeneralSecurityException, IOException {
|
throws GeneralSecurityException, IOException {
|
||||||
// Read the name, public key and signature
|
// Read the name, public key and signature
|
||||||
|
r.readListStart();
|
||||||
String name = r.readString(MAX_AUTHOR_NAME_LENGTH);
|
String name = r.readString(MAX_AUTHOR_NAME_LENGTH);
|
||||||
byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
|
byte[] publicKey = r.readRaw(MAX_PUBLIC_KEY_LENGTH);
|
||||||
byte[] sig = r.readRaw(MAX_SIGNATURE_LENGTH);
|
byte[] sig = r.readRaw(MAX_SIGNATURE_LENGTH);
|
||||||
|
r.readListEnd();
|
||||||
LOG.info("Received pseudonym");
|
LOG.info("Received pseudonym");
|
||||||
// Verify the signature
|
// Verify the signature
|
||||||
Signature signature = crypto.getSignature();
|
Signature signature = crypto.getSignature();
|
||||||
@@ -217,7 +256,6 @@ public class ContactExchangeTaskImpl extends Thread
|
|||||||
private void sendTimestamp(BdfWriter w, long timestamp)
|
private void sendTimestamp(BdfWriter w, long timestamp)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
w.writeLong(timestamp);
|
w.writeLong(timestamp);
|
||||||
w.flush();
|
|
||||||
LOG.info("Sent timestamp");
|
LOG.info("Sent timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,11 +266,56 @@ public class ContactExchangeTaskImpl extends Thread
|
|||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendTransportProperties(BdfWriter w,
|
||||||
|
Map<TransportId, TransportProperties> local) throws IOException {
|
||||||
|
w.writeListStart();
|
||||||
|
for (Entry<TransportId, TransportProperties> e : local.entrySet())
|
||||||
|
w.writeList(BdfList.of(e.getKey().getString(), e.getValue()));
|
||||||
|
w.writeListEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<TransportId, TransportProperties> receiveTransportProperties(
|
||||||
|
BdfReader r) throws IOException {
|
||||||
|
Map<TransportId, TransportProperties> remote =
|
||||||
|
new HashMap<TransportId, TransportProperties>();
|
||||||
|
r.readListStart();
|
||||||
|
while (!r.hasListEnd()) {
|
||||||
|
r.readListStart();
|
||||||
|
String id = r.readString(MAX_TRANSPORT_ID_LENGTH);
|
||||||
|
if (id.isEmpty()) throw new FormatException();
|
||||||
|
TransportProperties p = new TransportProperties();
|
||||||
|
r.readDictionaryStart();
|
||||||
|
while (!r.hasDictionaryEnd()) {
|
||||||
|
if (p.size() == MAX_PROPERTIES_PER_TRANSPORT)
|
||||||
|
throw new FormatException();
|
||||||
|
String key = r.readString(MAX_PROPERTY_LENGTH);
|
||||||
|
String value = r.readString(MAX_PROPERTY_LENGTH);
|
||||||
|
p.put(key, value);
|
||||||
|
}
|
||||||
|
r.readDictionaryEnd();
|
||||||
|
r.readListEnd();
|
||||||
|
remote.put(new TransportId(id), p);
|
||||||
|
}
|
||||||
|
r.readListEnd();
|
||||||
|
return remote;
|
||||||
|
}
|
||||||
|
|
||||||
private ContactId addContact(Author remoteAuthor, SecretKey master,
|
private ContactId addContact(Author remoteAuthor, SecretKey master,
|
||||||
long timestamp, boolean alice) throws DbException {
|
long timestamp, boolean alice,
|
||||||
// Add the contact to the database
|
Map<TransportId, TransportProperties> remoteProperties)
|
||||||
return contactManager.addContact(remoteAuthor, localAuthor.getId(),
|
throws DbException {
|
||||||
master, timestamp, alice, true);
|
ContactId contactId;
|
||||||
|
Transaction txn = db.startTransaction(false);
|
||||||
|
try {
|
||||||
|
contactId = contactManager.addContact(txn, remoteAuthor,
|
||||||
|
localAuthor.getId(), master, timestamp, alice, true);
|
||||||
|
transportPropertyManager.addRemoteProperties(txn, contactId,
|
||||||
|
remoteProperties);
|
||||||
|
txn.setComplete();
|
||||||
|
} finally {
|
||||||
|
db.endTransaction(txn);
|
||||||
|
}
|
||||||
|
return contactId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryToClose(DuplexTransportConnection conn,
|
private void tryToClose(DuplexTransportConnection conn,
|
||||||
|
|||||||
@@ -126,18 +126,18 @@ class ContactManagerImpl implements ContactManager, RemoveIdentityHook {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contactExists(Transaction txn, AuthorId remoteAuthorID,
|
public boolean contactExists(Transaction txn, AuthorId remoteAuthorId,
|
||||||
AuthorId localAuthorId) throws DbException {
|
AuthorId localAuthorId) throws DbException {
|
||||||
return db.containsContact(txn, remoteAuthorID, localAuthorId);
|
return db.containsContact(txn, remoteAuthorId, localAuthorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean contactExists(AuthorId remoteAuthorID,
|
public boolean contactExists(AuthorId remoteAuthorId,
|
||||||
AuthorId localAuthorId) throws DbException {
|
AuthorId localAuthorId) throws DbException {
|
||||||
boolean exists = false;
|
boolean exists = false;
|
||||||
Transaction txn = db.startTransaction(true);
|
Transaction txn = db.startTransaction(true);
|
||||||
try {
|
try {
|
||||||
exists = contactExists(txn, remoteAuthorID, localAuthorId);
|
exists = contactExists(txn, remoteAuthorId, localAuthorId);
|
||||||
txn.setComplete();
|
txn.setComplete();
|
||||||
} finally {
|
} finally {
|
||||||
db.endTransaction(txn);
|
db.endTransaction(txn);
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ import org.briarproject.api.contact.ContactManager;
|
|||||||
import org.briarproject.api.crypto.CryptoComponent;
|
import org.briarproject.api.crypto.CryptoComponent;
|
||||||
import org.briarproject.api.data.BdfReaderFactory;
|
import org.briarproject.api.data.BdfReaderFactory;
|
||||||
import org.briarproject.api.data.BdfWriterFactory;
|
import org.briarproject.api.data.BdfWriterFactory;
|
||||||
|
import org.briarproject.api.db.DatabaseComponent;
|
||||||
import org.briarproject.api.identity.AuthorFactory;
|
import org.briarproject.api.identity.AuthorFactory;
|
||||||
import org.briarproject.api.identity.IdentityManager;
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
|
||||||
import org.briarproject.api.plugins.ConnectionManager;
|
import org.briarproject.api.plugins.ConnectionManager;
|
||||||
|
import org.briarproject.api.properties.TransportPropertyManager;
|
||||||
import org.briarproject.api.system.Clock;
|
import org.briarproject.api.system.Clock;
|
||||||
import org.briarproject.api.transport.StreamReaderFactory;
|
import org.briarproject.api.transport.StreamReaderFactory;
|
||||||
import org.briarproject.api.transport.StreamWriterFactory;
|
import org.briarproject.api.transport.StreamWriterFactory;
|
||||||
@@ -28,22 +29,23 @@ public class ContactModule {
|
|||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
ContactManager getContactManager(LifecycleManager lifecycleManager,
|
ContactManager getContactManager(IdentityManager identityManager,
|
||||||
IdentityManager identityManager,
|
|
||||||
ContactManagerImpl contactManager) {
|
ContactManagerImpl contactManager) {
|
||||||
identityManager.registerRemoveIdentityHook(contactManager);
|
identityManager.registerRemoveIdentityHook(contactManager);
|
||||||
return contactManager;
|
return contactManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
ContactExchangeTask provideContactExchangeTask(
|
ContactExchangeTask provideContactExchangeTask(DatabaseComponent db,
|
||||||
AuthorFactory authorFactory, BdfReaderFactory bdfReaderFactory,
|
AuthorFactory authorFactory, BdfReaderFactory bdfReaderFactory,
|
||||||
BdfWriterFactory bdfWriterFactory, Clock clock,
|
BdfWriterFactory bdfWriterFactory, Clock clock,
|
||||||
ConnectionManager connectionManager, ContactManager contactManager,
|
ConnectionManager connectionManager, ContactManager contactManager,
|
||||||
|
TransportPropertyManager transportPropertyManager,
|
||||||
CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
|
CryptoComponent crypto, StreamReaderFactory streamReaderFactory,
|
||||||
StreamWriterFactory streamWriterFactory) {
|
StreamWriterFactory streamWriterFactory) {
|
||||||
return new ContactExchangeTaskImpl(authorFactory, bdfReaderFactory,
|
return new ContactExchangeTaskImpl(db, authorFactory, bdfReaderFactory,
|
||||||
bdfWriterFactory, clock, connectionManager, contactManager,
|
bdfWriterFactory, clock, connectionManager, contactManager,
|
||||||
crypto, streamReaderFactory, streamWriterFactory);
|
transportPropertyManager, crypto, streamReaderFactory,
|
||||||
|
streamWriterFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user