diff --git a/src/XMPPConnection.h b/src/XMPPConnection.h index bb89f69..06b3ee2 100644 --- a/src/XMPPConnection.h +++ b/src/XMPPConnection.h @@ -67,7 +67,7 @@ OFTCPSocket *sock; OFXMLParser *parser, *oldParser; OFXMLElementBuilder *elementBuilder, *oldElementBuilder; - OFString *username, *password, *server, *resource; + OFString *username, *password, *server, *domain, *resource; XMPPJID *JID; uint16_t port; id delegate; @@ -79,7 +79,7 @@ } #ifdef OF_HAVE_PROPERTIES -@property (copy) OFString *username, *password, *server, *resource; +@property (copy) OFString *username, *password, *server, *domain, *resource; @property (copy, readonly) XMPPJID *JID; @property (assign) uint16_t port; @property (retain) id delegate; @@ -139,6 +139,8 @@ - (OFString*)password; - (void)setServer: (OFString*)server; - (OFString*)server; +- (void)setDomain: (OFString*)domain; +- (OFString*)domain; - (void)setResource: (OFString*)resource; - (OFString*)resource; - (XMPPJID*)JID; diff --git a/src/XMPPConnection.m b/src/XMPPConnection.m index 1da719f..d7c5acd 100644 --- a/src/XMPPConnection.m +++ b/src/XMPPConnection.m @@ -77,6 +77,7 @@ [username release]; [password release]; [server release]; + [domain release]; [resource release]; [JID release]; [delegate release]; @@ -171,6 +172,33 @@ return [[server copy] autorelease]; } +- (void)setDomain: (OFString*)domain_ +{ + OFString *old = domain; + char *srv; + Stringprep_rc rc; + + if ((rc = stringprep_profile([domain_ cString], &srv, + "Nameprep", 0)) != STRINGPREP_OK) + @throw [XMPPStringPrepFailedException newWithClass: isa + connection: self + profile: @"Nameprep" + string: domain_]; + + @try { + domain = [[OFString alloc] initWithCString: srv]; + } @finally { + free(srv); + } + + [old release]; +} + +- (OFString*)domain +{ + return [[domain copy] autorelease]; +} + - (void)setPassword: (OFString*)password_ { OFString *old = password; @@ -201,25 +229,57 @@ - (void)connect { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - XMPPSRVLookup *SRVLookup = [XMPPSRVLookup lookupWithDomain: server]; - OFEnumerator *enumerator = [SRVLookup objectEnumerator]; - XMPPSRVEntry *candidate; + XMPPSRVEntry *candidate = nil; + XMPPSRVLookup *SRVLookup; + OFEnumerator *enumerator; + OFString *domainToASCII; + char *cDomainToASCII; + Idna_rc rc; - while ((candidate = [enumerator nextObject]) != nil) { - @try { - [sock connectToHost: [candidate target] - onPort: [candidate port]]; - break; - } @catch (OFAddressTranslationFailedException *e) { - [e release]; - } @catch (OFConnectionFailedException *e) { - [e release]; - } - } - - if (!candidate) + if (server) [sock connectToHost: server onPort: port]; + else { + if ((rc = idna_to_ascii_8z([domain cString], &cDomainToASCII, + IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS) + @throw [XMPPIDNATranslationFailedException + newWithClass: isa + connection: self + operation: @"ToASCII" + string: domain]; + + @try { + domainToASCII = [OFString + stringWithCString: cDomainToASCII]; + } @finally { + free(cDomainToASCII); + } + + @try { + SRVLookup = [XMPPSRVLookup + lookupWithDomain: domainToASCII]; + enumerator = [SRVLookup objectEnumerator]; + + while ((candidate = [enumerator nextObject]) != nil) { + @try { + [sock connectToHost: [candidate target] + onPort: [candidate port]]; + break; + } @catch (OFAddressTranslationFailedException + *e) { + [e release]; + } @catch (OFConnectionFailedException *e) { + [e release]; + } + } + } @catch (OFAddressTranslationFailedException *e) { + [e release]; + } + + if (!candidate) + [sock connectToHost: domainToASCII + onPort: port]; + } [self XMPP_startStream]; @@ -294,7 +354,7 @@ enumerator = [attributes objectEnumerator]; while ((attribute = [enumerator nextObject]) != nil) { if ([[attribute name] isEqual: @"from"] && - ![[attribute stringValue] isEqual: server]) { + ![[attribute stringValue] isEqual: domain]) { of_log(@"Got invalid from in stream start!"); assert(0); } @@ -369,7 +429,7 @@ @"", server]; + @"version='1.0'>", domain]; } - (void)XMPP_handleStanza: (OFXMLElement*)element diff --git a/tests/test.m b/tests/test.m index c85820d..aae4b94 100644 --- a/tests/test.m +++ b/tests/test.m @@ -97,7 +97,7 @@ OF_APPLICATION_DELEGATE(AppDelegate) [OFApplication terminateWithStatus: 1]; } - [conn setServer: [arguments objectAtIndex: 0]]; + [conn setDomain: [arguments objectAtIndex: 0]]; [conn setUsername: [arguments objectAtIndex: 1]]; [conn setPassword: [arguments objectAtIndex: 2]]; [conn setResource: @"ObjXMPP"];