Wrote a simple FIFO queue class
[ITFoundation.git] / ITInetSocket.m
1 //
2 //  ITInetSocket.m
3 //  ITFoundation
4 //
5 //  Created by Alexander Strange on Tue Feb 11 2003.
6 //  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "ITInetSocket.h"
10 #import <sys/socket.h>
11 #import <arpa/inet.h>
12
13 @interface ITInetSocket(Debugging)
14 -(NSString*)dumpv6Addrinfo:(struct addrinfo *)_ai;
15 @end
16
17 @implementation ITInetSocket
18 -(id)initWithFD:(int)fd delegate:(id)d
19 {
20     if (self = [super init])
21            {
22            state = ITInetSocketListening;
23            sockfd = fd;
24            delegate = [d retain];
25            port = 0;
26            writeBuffer = nil;
27            ai = nil;
28            }
29     return self;
30 }
31
32 -(id)initWithDelegate:(id)d
33 {
34     if (self = [super init])
35            {
36            state = ITInetSocketDisconnected;
37            sockfd = -1;
38            delegate = [d retain];
39            port = 0;
40            writeBuffer = nil;
41            ai = nil;
42            }
43     return self;
44 }
45
46 -(void) connectToHost:(NSString*)host onPort:(short)thePort
47 {
48     if (state == ITInetSocketDisconnected)
49            {
50            struct addrinfo hints;
51            int err;
52            const char *portNam = [[[NSNumber numberWithShort:thePort] stringValue] cString], *hostCStr = [host cString];
53
54            hints.ai_flags = 0;
55            hints.ai_family = PF_INET6;
56            hints.ai_socktype = SOCK_STREAM;
57            hints.ai_protocol = IPPROTO_TCP;
58            hints.ai_canonname = NULL;
59            hints.ai_addr = NULL;
60            hints.ai_next = NULL;
61
62            err = getaddrinfo(hostCStr,portNam,&hints,&ai);
63            if (err == EAI_NODATA) //it's a dotted-decimal IPv4 string, so we use v6compat stuff now
64            {
65                   err = getaddrinfo([[NSString stringWithFormat:@"ffff::%s",hostCStr] cString],portNam,&hints,&ai);
66            }
67            NSLog([self dumpv6Addrinfo:ai]);
68            }
69 }
70
71 -(ITInetSocketState)state
72 {
73     return state;
74 }
75 @end
76
77 @implementation ITInetSocket(Debugging)
78 -(NSString*)dumpv6Addrinfo:(struct addrinfo *)_ai
79 {
80     const char *cfmt =
81     "\{\n"
82     "Flags = %x\n"
83     "Family = %x\n"
84     "Socktype = %x\n"
85     "Protocol = %x\n"
86     "Canonname = %s\n"
87     "Sockaddr = \n"
88     "{\n"
89     "\tLength = %x\n"
90     "\tFamily = %x\n"
91     "\tPort = %d\n"
92     "\tFlowinfo = %x\n"
93     "\tAddr = {%#lx,%#lx,%#lx,%#lx}\n"
94     "\tScope = %x\n"
95     "}\n"
96     "Next = ";
97     NSString *nsfmt = [NSString stringWithCString:cfmt];
98     NSMutableString *buf = [[[NSMutableString alloc] init] autorelease];
99
100     do
101            {
102                   struct sockaddr_in6 *sa = (struct sockaddr_in6 *)_ai->ai_addr;
103                   [buf appendFormat:nsfmt,_ai->ai_flags,_ai->ai_family,_ai->ai_socktype,_ai->ai_protocol,_ai->ai_canonname?_ai->ai_canonname:"",sa->sin6_len,sa->sin6_family,sa->sin6_port,sa->sin6_flowinfo,sa->sin6_addr.__u6_addr.__u6_addr32[0],sa->sin6_addr.__u6_addr.__u6_addr32[1],sa->sin6_addr.__u6_addr.__u6_addr32[2],sa->sin6_addr.__u6_addr.__u6_addr32[3],sa->sin6_scope_id];
104            }
105     while (_ai = _ai->ai_next);
106     [buf appendString:@"nil\n}"];
107     return buf;
108 }
109 @end