I have to make a VPN connection with protocol IKEv2 using a certificate.
I already have the Network Extensions entitlements.
Starting with the certificate that i'm using:
I request that certificate with an ACS request that returns me the UserCertificate in Base64 that i need to send with the VPN connection.
Example User Certificate in Base64 received:
"MIIFqTCCA5GgAwIBAgIQdwPEs5oyDHNNp7e2ZyhwADANBgkqhkiG9w0 ... N972fR4pncgdIA=="
In order to pass that certificate in the "identityData" parameter i have to convert this to Data with the PKCS12 format as i understand.
This is my conversion from Base64 to Data:
certificate = SecCertificateCreateWithData(nil, Data(base64Encoded: "Base64_String_Here")! as CFData)!
certificateData = SecCertificateCopyData(certificate!) as Data
I'm able to print the Data as NSData and i get this example:
308205a9 30820391 a0030201 02021077 03c4b39a 320c734d a7b7b667 28700030 0d06092a 864886f7 0d01010b 05003060
311c301a 06035504 030c1354 45535420 5646435a 20455043 20537562 4341310c 300a0603 55040b0c 03455043 31253023
06035504 0a0c1c56 6f646166 6f6e6520 437a6563 68205265 7075626c 69632061 2e732e31 0b300906 03550406 1302435a
301e170d 31373131 31373131 32393531 5a170d31 39313131 38313132 3935315a 30818731 43304106 03550403 0c3a3467
66693233 30303339 39303030 30313433 31403467 66692e65 70632e6d 6e633030 332e6d63 63323330 2e336770 706e6574
776f726b 2e6f7267 310c300a 06035504 0b0c0345 50433125 30230603 55040a0c 1c566f64 61666f6e 6520437a 65636820
52657075 626c6963 20612e73 2e310b30 09060355 04061302 435a3082 0122300d 06092a86 4886f70d 01010105 00038201
0f003082 010a0282 010100cc 5effc8d7 fb357559 678fb8fc 48fd3558 8af4f236 a27295a6 b484bad0 921f8077 35ddbceb
5c064492 2f9df462 2a44c4fc 85b80cfa eec6b84b b13aefa1 69e4e6b3 db8ef30b 202229c7 421bfb8f 3f47c24f 6e3f7abc
ca7d216b 31d2a02c 94c3ef6c 9d50c2ab a590d99f 5d7afddb acbcc045 53949653 97034063 404cbe00 6aaec239 b37b2ce9
5c63d126 127247a5 75446c6b fa2e2217 6706a36c a0db0630 dac90d10 00ff24a8 2f189f18 37233151 f9825f60 aa8f66e7
89d656b9 5a52d9e3 b52cb3bc 5badb801 d9ea3685 8930cb3b 490ccba0 247f4bde 00b46d5e a63b1018 4ad8a581 978f5570
82f06f7f ba60db83 abcb4391 2f221e69 14bbdc46 ce19ae95 33773f02 03010001 a3820135 30820131 30370608 2b060105
05070101 042b3029 30270608 2b060105 05073001 861b6874 74703a2f 2f6f6373 702d6570 632e766f 6461666f 6e652e63
7a301d06 03551d0e 04160414 ea45a2e8 94fe37bc 08af3fab 60f9869b 5980d3cf 30090603 551d1304 02300030 1f060355
1d230418 30168014 f3c6b0f4 961565ab 232c6060 3e16f790 f63334b1 30440603 551d2004 3d303b30 39060960 86480186
f8420108 302c302a 06082b06 01050507 0201161e 68747470 3a2f2f70 6b692e76 6f646166 6f6e652e 637a2f70 6f6c6963
792f3040 0603551d 1f043930 373035a0 33a03186 2f687474 703a2f2f 706b692e 766f6461 666f6e65 2e637a2f 63726c2f
74657374 5f766663 7a5f6570 635f6361 2e63726c 300e0603 551d0f01 01ff0404 030203f8 30130603 551d2504 0c300a06
082b0601 05050703 02300d06 092a8648 86f70d01 010b0500 03820201 004cacde 1d7b7843 43aa546c 8984e308 57a12a27
0b9a2873 2adb598d da29fe4c ee087c92 3f18bbaa 1f3ef0b9 39e18d50 db982f87 36689c03 07ab7d11 a1665bf0 f6057de5
e89fe2fe 3f9c476b 8a28749c f9d7636c 8ece6012 d0a53902 ec437171 0af85024 0963bf85 518fa150 43dc7fe8 30c42f09
62cd2a31 c38e54ba de2b8a01 6e6804b2 b66c36c1 4626fc37 65064a65 d5087412 8e541e12 51525c4c e1f4a7e2 94a31397
2806d327 7a3c65c7 50e7db59 99460ae9 a446391e 5bbce05e 1f205e1c 118cd7aa 02e9881f 75b5b40d f2aa09bc bb7abf22
b11b3e31 2f0e78ae ee497d26 ef314b1d f16008af c433a653 983db0a9 97cbbca1 5a9e8d4d 3d34ee87 858e4f3d d2c5c111
05ccdcfa b1a41afe 2624ba31 decd561a 791e97e0 197b8bfe 97ebb3ad 7b511c1d e820c83f 81cdb9ed 21d59b49 7fb0bb39
69e735e7 350af763 ab26ee3d 7e954ef7 e5c994f6 c8f104ac 4f19ed25 9855f14c 619935d6 0d9f1206 910ffe03 74c312d5
b39da039 650d9004 e2186914 cfa19052 a2e47f1c 5af90903 959ab99f 2c52a9d8 f737b59f 00cababa 0b4f7236 e9102ee4
a76ed0a0 6d827860 653d6e62 f52fcc77 d9afdc90 53d942fe 434c8901 ab2a93e8 cc7c8555 eb6a94e5 0e1cc18c 9d6c8b48
ed9204eb 623f74d2 219a5ca9 032caa7c 900ed208 b88f5fb2 5c53bcd3 e82c48f8 80450f40 f05706c1 072427cb 815e8590
4fbf5137 def67d1e 299dc81d 20
So, basically the var certificateData is the one that i'm using in the parameter "identityData".
Here is what i do in order to connect the VPN:
First i set all the parameters that are required:
vpnManager = NEVPNManager.shared()
vpnManager!.loadFromPreferences { error in
var hasProtocolConfig = false;
if #available(iOS 9, *) {
hasProtocolConfig = self.vpnManager!.protocolConfiguration != nil
} else {
hasProtocolConfig = self.vpnManager!.`protocol` != nil
}
if hasProtocolConfig == true {
let p = NEVPNProtocolIKEv2()
p.serverAddress = "X.X.X.X"
p.localIdentifier = "My_Local_Identifier"
p.remoteIdentifier = "My_Remote_Identifier"
p.identityData = certificateData
p.ikeSecurityAssociationParameters.integrityAlgorithm = NEVPNIKEv2IntegrityAlgorithm.SHA256
p.ikeSecurityAssociationParameters.encryptionAlgorithm = NEVPNIKEv2EncryptionAlgorithm.algorithmAES128
p.ikeSecurityAssociationParameters.diffieHellmanGroup = NEVPNIKEv2DiffieHellmanGroup.group14
p.serverCertificateIssuerCommonName = "My_IssuerCommonName"
p.serverCertificateCommonName = "My_CommonName"
p.authenticationMethod = NEVPNIKEAuthenticationMethod.certificate
p.useExtendedAuthentication = true
p.disconnectOnSleep = false
if #available(iOS 9, *) {
self.vpnManager.protocolConfiguration = p
} else {
self.vpnManager.`protocol` = p
}
self.vpnManager.isEnabled = true
self.vpnManager.saveToPreferences { error in
if let e = error{
print("[VPN] error saving: " + e.localizedDescription)
} else {
print("[VPN] vpn saved")
Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.connectVPN), userInfo: nil, repeats: false)
}
return
}
Then i establish the VPN connection:
do {
try vpnManager!.connection.startVPNTunnel()
} catch let error {
print("Error starting VPN Connection \(error.localizedDescription)");
}
If i understand this well, Since i am not able to force the "Notify: EAP_ONLY_AUTHENTICATION", i have to use "NEVPNIKEAuthentication.certificate", otherwise i could set it to ".none".
The ikeAssociationParameters are the right ones as i check with the server side.
When i try to connect to the VPN i get the status:
Connecting -> Disconnected
Any ideia of what i am doing wrong with this connection?
Related
I am working on an event-driven server in Rust and want it able to connect it to maximum no of clients possible.
But only up to 700 clients I am able to connect and send data at the same time. If I try to increase the clients, client connections from client side start breaking. I am using threads to create multiple clients, it starts giving the following error:
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value:
Os { code: 104, kind: ConnectionReset, message: "Connection reset by peer" }',
src/libcore/result.rs
If data sending is disabled it is able to connect 1017 clients and can be increased by allowing a process to open more files than 1024.
I checked the max. no of threads that can be created in my os is 62096. Memory usage of the server program is also around 15KB.
I tried to increase the event loop capacity to 20,480 still it is not supporting 800 clients.
Server.rs:
extern crate mio;
use mio::net::{TcpListener, TcpStream};
use mio::*;
use mio::{Poll, PollOpt, Ready, Token};
use std::collections::HashMap;
use std::env;
use std::io::{Error, Read, Write};
fn process_events(
e: Event,
listener: &TcpListener,
poll: &Poll,
clients: &mut HashMap<Token, TcpStream>,
mut count: usize,
) {
if e.token() == Token(0) {
match listener.accept() {
Ok((mut stream, addr)) => {
let new_token = Token(count);
println!("new token {:?}", new_token);
poll.register(
&stream,
new_token,
Ready::readable(),
PollOpt::edge() | PollOpt::oneshot(),
)
.unwrap();
println!("Got a client: {:?}", stream.peer_addr().unwrap());
clients.insert(new_token, stream);
}
Err(e) => panic!("Error during connection{}", e),
}
}
if e.token() != Token(0) && e.readiness().is_readable() {
let mut buf = [0; 512];
let mut t = e.token();
let reader = clients.get_mut(&e.token()).unwrap().read(&mut buf);
match reader {
Ok(_) => {
let bytes_no = reader.unwrap();
println!("No of bytes read : {:?}, {:?}", bytes_no, e.token());
}
Err(e) => {
println!("could not read: {}", e);
}
}
poll.reregister(
&clients[&e.token()],
e.token(),
Ready::readable(),
PollOpt::edge() | PollOpt::oneshot(),
)
.unwrap();
}
}
fn main() {
const server: Token = Token(0);
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
eprintln!("Provide the argument");
std::process::exit(1);
}
let listen = &args[1];
let addr = listen.parse().unwrap();
let mut listener = TcpListener::bind(&addr).expect("Could not bind");
println!("Server listening on : {}", addr);
let mut clients = HashMap::new();
let mut eve = Events::with_capacity(20480);
let poll = Poll::new().unwrap();
let mut count = 1;
poll.register(
&listener,
server,
Ready::readable(),
PollOpt::edge() | PollOpt::oneshot(),
)
.unwrap();
loop {
poll.poll(&mut eve, None);
for e in &eve {
process_events(e, &listener, &poll, &mut clients, count);
if e.token() == Token(0) {
count += 1;
}
}
poll.reregister(
&listener,
server,
Ready::readable(),
PollOpt::edge() | PollOpt::oneshot(),
)
.unwrap();
}
}
Client.rs:
use std::io;
use std::io::Write;
use std::net::TcpStream;
use std::thread;
fn handle_client() {
let server_addr = String::from("localhost:3000");
if let Ok(mut stream) = TcpStream::connect(server_addr) {
println!("Connected to server {} ", c);
let msg = [0u8; 512];
loop {
stream.write(&msg).unwrap();
}
} else {
println!("could not connect");
}
}
fn main() {
for _i in 0..10000 {
thread::spawn(move || handle_client());
}
}
As the event-driven approach is better than the multi-threaded server, expected clients should more than 1020.
I´m using CocoaMQTT and trying to connect to a MQTT service, with the following code:
let clientID = "CocoaMQTT-" + String(ProcessInfo().processIdentifier)
//This is myHost: wss://myserver.test:9001
let mqtt = CocoaMQTT(clie.ntID: clientID, host: "myserver.test", port: 9001)
mqtt.keepAlive = 10000
mqtt.username = "username"
mqtt.password = "password"
mqtt.enableSSL = true
mqtt.delegate = self
mqtt.connect()
mqtt.autoReconnect = true
I get the error: Error Domain=GCDAsyncSocketErrorDomain Code=7 "Socket closed by remote peer" UserInfo={NSLocalizedDescription=Socket closed by remote peer}
Does CocoaMQTT support wss or only tcp? If it doesnt support, is there any other client for swift?
This is a example from CocoaMQTT. Maybe it helps.
let clientID = "CocoaMQTT-\(animal!)-" + String(ProcessInfo().processIdentifier)
mqtt = CocoaMQTT(clientID: clientID, host: "127.0.0.1", port: 8883)
mqtt!.username = ""
mqtt!.password = ""
mqtt!.willMessage = CocoaMQTTWill(topic: "/will", message: "dieout")
mqtt!.keepAlive = 60
mqtt!.delegate = self
mqtt!.enableSSL = true
let clientCertArray = getClientCertFromP12File(certName: "client-keycert", certPassword: "MySecretPassword")
var sslSettings: [String: NSObject] = [:]
sslSettings[GCDAsyncSocketManuallyEvaluateTrust as String] = NSNumber(value: true)
sslSettings[kCFStreamSSLCertificates as String] = clientCertArray
mqtt!.sslSettings = sslSettings
Hello Community and first things First:
dovecot --version
2.2.9
dovecot -n
# 2.2.9: /etc/dovecot/dovecot.conf
# OS: Linux 3.13.0-042stab125.5 x86_64 Ubuntu 14.04.5 LTS
auth_mechanisms = plain login
dict {
sqlquota = mysql:/etc/dovecot/dovecot-dict-sql.conf
}
listen = *,[::]
log_timestamp = "%Y-%m-%d %H:%M:%S "
login_log_format_elements = user=<%u> method=%m rip=%r lip=%l mpid=%e %c %k
mail_fsync = always
mail_home = /var/vmail/%d/%n
mail_location = maildir:~/
mail_nfs_index = yes
mail_nfs_storage = yes
mail_plugins = quota acl
vmanagesieve_notify_capability = mailto
managesieve_sieve_capability = fileinto reject envelope encoded-character vacation subaddress comparator-i;ascii-numeric relational regex imap4flags copy include variables body enotify environment mailbox date ihave
mmap_disable = yes
namespace {
list = yes
location = maildir:%%h/:INDEXPVT=~/Shared/%%u
prefix = Shared/%%u/
separator = /
subscriptions = yes
type = shared
}
namespace inbox {
inbox = yes
location =
mailbox Archiv {
special_use = \Archive
}
mailbox Archive {
auto = subscribe
special_use = \Archive
}
mailbox Archives {
special_use = \Archive
}
mailbox "Deleted Messages" {
special_use = \Trash
}
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
mailbox Entwürfe {
special_use = \Drafts
}
mailbox "Gelöschte Objekte" {
special_use = \Trash
}
mailbox Gesendet {
special_use = \Sent
}
mailbox Junk {
auto = subscribe
special_use = \Junk
}
mailbox Papierkorb {
special_use = \Trash
}
mailbox Sent {
auto = subscribe
special_use = \Sent
}
mailbox "Sent Messages" {
special_use = \Sent
}
mailbox Trash {
auto = subscribe
special_use = \Trash
}
prefix =
separator = /
}
passdb {
args = /etc/dovecot/dovecot-mysql.conf
driver = sql
}
plugin {
acl = vfile
acl_anyone = allow
acl_shared_dict = file:/var/vmail/shared-mailboxes.db
quota = dict:User quota::proxy::sqlquota
quota_rule2 = Trash:storage=+100%%
sieve = /var/vmail/sieve/%u.sieve
sieve_after = /var/vmail/sieve/global.sieve
sieve_max_script_size = 1M
sieve_quota_max_scripts = 0
sieve_quota_max_storage = 0
}
protocols = imap sieve lmtp pop3
service auth {
unix_listener /var/spool/postfix/private/auth_dovecot {
group = postfix
mode = 0660
user = postfix
}
unix_listener auth-master {
mode = 0600
user = vmail
}
unix_listener auth-userdb {
mode = 0600
user = vmail
}
user = root
}
service dict {
unix_listener dict {
group = vmail
mode = 0660
user = vmail
}
}
service lmtp {
unix_listener /var/spool/postfix/private/dovecot-lmtp {
group = postfix
mode = 0600
user = postfix
}
user = vmail
}
service managesieve-login {
inet_listener sieve {
port = 4190
}
process_min_avail = 2
service_count = 1
vsz_limit = 128 M
}
service managesieve {
process_limit = 256
}
ssl_cert = </etc/ssl/mail/mail.crt
ssl_cipher_list = EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECD H:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5 :!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128- SHA:AES128-SHA
ssl_dh_parameters_length = 2048
ssl_key = </etc/ssl/mail/mail.key
ssl_protocols = !SSLv3 !SSLv2
userdb {
args = /etc/dovecot/dovecot-mysql.conf
driver = sql
}
protocol imap {
mail_plugins = quota imap_quota imap_acl acl
}
protocol lmtp {
auth_socket_path = /var/run/dovecot/auth-master
mail_plugins = quota sieve acl
postmaster_address = postmaster#domain1.com
}
protocol sieve {
managesieve_logout_format = bytes=%i/%o
}
remote 127.0.0.1 {
disable_plaintext_auth = no
}
Mail.err
Nov 13 23:59:06 webdev dovecot: auth: Error: PLAIN(account#domain2.com, XXX.XXX.XXX.XXX,<y869CoDETEST4dHk>): Request 29154.1 timed out after 150 secs, state=1
Mail.log
Nov 13 23:27:54 webdev dovecot: auth: Error: LOGIN(account#domain1.com,IP.IP.IP.IP,<oN4ly+TestDZ6dHk>): Request 28118.1 timed out after 150 secs, state=1
Nov 13 23:27:57 webdev dovecot: auth: Error: PLAIN( account#domain2.com,XXX.XXX.XXX.XXX,<FAxKe+JaatES7tHk>): Request 28120.1 timed out after 150 secs, state=1
Nov 13 23:28:24 webdev dovecot: imap-login: Disconnected: Inactivity during authentication (disconnected while authenticating, waited 180 secs): user=<>, method=LOGIN, rip=ClientIP, lip=ServerIP, TLS: Disconnected, TLSv1.2 with cipher DHE-RSA-AES128-GCM-SHA256 (128/128 bits)
[...]
Nov 13 23:47:15 webdev dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=84.119.151.17, lip=62.75.185.32
I did not change anything on my client nor serverside setup and i suddenly could not reach the Mailserver anymore. Obviously I can reach the Server using SSH or HTTP.
I hope I provided all infos you need to help me in this situation. And am grateful for every hint to solve this as I dont even have a clue what to look for.
The error messages are talking about a timeout on the authentication, and the config shows that the authentication is using a MySQL database. For this reason I would check if the MySQL process is still up, or restart the service (if it's running as a service, which is probably the case).
I trying to connect to Google with OAuth2. I have got access_token and user email. Here is not problem.
let singleton: Singleton = Singleton.sharedInstance
singleton.session.authType = MCOAuthType.XOAuth2 // session:IMAPSession
singleton.session.OAuth2Token = singleton.accessToken
singleton.session.username = singleton.email
singleton.session.hostname = "imap.gmail.ru"
singleton.session.port = 993
singleton.session.connectionType = MCOConnectionType.StartTLS
Next step i create fetch operation and get an error
let requestKind = MCOIMAPMessagesRequestKind.Headers | MCOIMAPMessagesRequestKind.Flags | MCOIMAPMessagesRequestKind.Structure
let uids = MCOIndexSet(range: MCORangeMake(1, UINT64_MAX))
let folder = "INBOX"
let fetchOperation = singleton.session.fetchMessagesOperationWithFolder(folder, requestKind: requestKind, uids: uids)
fetchOperation.start { (error, fetchedMessages, vanishedMessages) -> Void in
if (error != nil)
{
println("Error: \(error)") // this line return me error
}
Error: Error Domain=MCOErrorDomain Code=1 "A stable connection to the server could not be established." UserInfo=0x7f9e260036b0 {NSLocalizedDescription=A stable connection to the server could not be established.}
Error: Error Domain=MCOErrorDomain Code=1 "A stable connection to the server could not be established." UserInfo=0x7f9e23c46c00 {NSLocalizedDescription=A stable connection to the server could not be established.}
what could be the problem?
Here's the working code guys:
var smtpSession = MCOSMTPSession()
smtpSession.hostname = "xxxxxxxx"
smtpSession.username = "xxxxxxx"
smtpSession.password = "xxxxxxxx"
smtpSession.port = 8465
smtpSession.authType = MCOAuthType.SASLPlain
smtpSession.connectionType = MCOConnectionType.TLS
smtpSession.connectionLogger = {(connectionID, type, data) in
if data != nil {
if let string = NSString(data: data, encoding: NSUTF8StringEncoding){
NSLog("Connectionlogger: \(string)")
}
}
}
var builder = MCOMessageBuilder()
builder.header.to = [MCOAddress(displayName: "Rool", mailbox: "xxxxxxx#hxxxx.com")]
builder.header.from = MCOAddress(displayName: "Matt R", mailbox: "xxxxxx#sxxxxxx.com")
builder.header.subject = "My message"
builder.htmlBody = "<h3>This is a test message!</h3>"
let rfc822Data = builder.data()
let sendOperation = smtpSession.sendOperationWithData(rfc822Data)
sendOperation.start { (error) -> Void in
if (error != nil) {
NSLog("Error sending email: \(error)")
} else {
NSLog("Successfully sent email!")
}
}
PS: I used this code for SMTP2GO and It's working flawlessly, just make sure you're using the right port.
I am really new to Network programming and using GCDAsyncSocket for the first time. I am trying to implement an iOS app where 1 device acts a host and other devices(browsers) connect to it. I am using NSNetService/NSNetServiceBrowser for publishing/browsing part.
Now, my client/browser resolves the host's address properly and try to connect to it using following code:
func netServiceDidResolveAddress(sender: NSNetService) {
// Connect with Service
if (self.connectWithService(sender, hostname: sender.hostName!)) {
println("Connecting with service: domainName= \(sender.domain), type= \(sender.type), name= \(sender.name), onPort= \(sender.port) and hostname: \(sender.hostName!)");
} else {
println("Unable to connect with service: domainName= \(sender.domain), type= \(sender.type), name= \(sender.name), onPort= \(sender.port)");
}
}
private func connectWithService(service: NSNetService, hostname: String) ->Bool {
var isConnecting:Bool = false;
if (self.browserSocket == nil || !(self.browserSocket?.isConnected)!) {
// Initialize Socket
self.browserSocket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue());
// Connect
while (!isConnecting){
var error: NSError?;
println("Connecting port : \(service.port) and hostname: \(hostname)");
if (self.browserSocket.connectToHost(hostname, onPort: UInt16(service.port), error: &error)) {
isConnecting = true;
} else if (error != nil) {
println("Unable to connect to address. Error \(error) with user info \(error?.userInfo)");
}
}
} else {
println("Connecting is: \(self.browserSocket.isConnected)");
isConnecting = self.browserSocket.isConnected;
}
return isConnecting;
}
// GCDAsyncSocketDelegate methods
func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16) {
println("Socket: \(sock) Did connect to host: \(host) on port:\(port)");
// Start Reading
sock.readDataToLength(UInt(sizeof(UInt64)), withTimeout: -1.0, tag: 0);
}
func socketDidDisconnect(sock: GCDAsyncSocket!, withError err: NSError!) {
println("Socket \(sock) did disconnect with error \(err?)");
}
Following is the Publisher code:
override func viewDidLoad() {
super.viewDidLoad()
let barButton = UIBarButtonItem(title: "Stop Publishing", style: .Done, target: self, action: "stopPublishing");
self.navigationItem.rightBarButtonItem = barButton;
// Publish the service
self.publishService();
}
// MARK: Button callbacks
private func publishService() {
// Initialize GCDAsyncSocket
self.socket = GCDAsyncSocket(delegate: self, delegateQueue: dispatch_get_main_queue());
// Start listening for incoming connections
var error: NSError?;
if (self.socket.acceptOnPort(0, error: &error)) {
// Initialize Service
self.service = NSNetService(domain: "local.", type: "_mpstest._tcp", name: UIDevice.currentDevice().name, port:0);
// Configure Service
self.service.delegate = self;
self.service.includesPeerToPeer = true;
self.service.publishWithOptions(.ListenForConnections);
} else {
println("Unable to create socket. Error \(error?.description) with user info \(error?.userInfo)");
}
}
Now, the client connects with the host and hits following method:
func socket(sock: GCDAsyncSocket!, didConnectToHost host: String!, port: UInt16) {
But then it immediately disconnects hitting following method with ErrorCode =7 "Socket closed by remote peer"
func socketDidDisconnect(sock: GCDAsyncSocket!, withError err: NSError!) {
Following is the console log from Browser device:
Service found is : <NSNetService 0x15e2f710> local. _mpstest._tcp. iPad 30
Connecting port : 50797 and hostname: iPad-30.local.
Connecting with service: domainName= local., type= _mpstest._tcp., name= iPad 30, onPort= 50797 and hostname: iPad-30.local.
Socket <GCDAsyncSocket: 0x15d80020> did disconnect with error Optional(Error Domain=kCFStreamErrorDomainNetDB Code=8 "nodename nor servname provided, or not known" UserInfo=0x15e3c7a0 {NSLocalizedDescription=nodename nor servname provided, or not known})
Connecting port : 50797 and hostname: iPad-30.local.
Connecting with service: domainName= local., type= _mpstest._tcp., name= iPad 30, onPort= 50797 and hostname: iPad-30.local.
Socket: <GCDAsyncSocket: 0x15e59c20> Did connect to host: 169.254.78.98 on port:50797
Socket <GCDAsyncSocket: 0x15e59c20> did disconnect with error Optional(Error Domain=GCDAsyncSocketErrorDomain Code=7 "Socket closed by remote peer" UserInfo=0x15e5b070 {NSLocalizedDescription=Socket closed by remote peer})
Host socket delegate methods are never hit.
I am really stuck here. Any help as to what am I doing wrong here would be great.
Thanks
Vik
I had the same error as well! After much searching and pulling my hair out I stumbled upon a solution that has something to do with the weak declaration for GCDAsyncSocket, ARC in Swift understands the declaration "__weak" in GCDAsyncSocket.m as an excuse to deallocate the socket as quickly as possible.
Search for the keyword "__weak" in your project and remove all the references.
found this solution at: Delegate not getting set