2 // C Implementation: session
7 // Author: Felix Bechstein <f@ub0r.de>, (C) 2007
9 // Copyright: See COPYING file that comes with this distribution
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
33 void session_get_type(int sockd
, int *port
, char* buffer
, int buflen
, int *l
)
35 *port
= 0; // initial value
37 int traffic_type
= TYPE_UNDEFINED
;
38 *l
= recv(sockd
, buffer
, buflen
, MSG_DONTWAIT
); // MSG_PEEK does not work here! -> return buffer and send it to client later
40 if (*l
< 0) // error occured (no data in queue)
42 // try again after a little while
43 unsigned int s
= CONNECTION_TIMEOUT
;
45 *l
= recv(sockd
, buffer
, buflen
, MSG_DONTWAIT
);
48 if (*l
== 0) // socket is closed
51 if (*l
> 0) // data in there. so let's analyse it
53 traffic_type
= DEFAULT_TRAFFIC
;
55 // test for hstop3g traffic -- start
56 char HSTOP3G_PATTERN
[] = {0x13,0x01,0x00,0x00,0x27};
57 int HSTOP3G_PATTERN_LEN
= 5;
60 if (*l
> HSTOP3G_PATTERN_LEN
)
61 minl
= HSTOP3G_PATTERN_LEN
;
62 traffic_type
= TYPE_HSTOP3G
;
64 for (i
= 0; i
< minl
; i
++) {
65 if (buffer
[i
] != HSTOP3G_PATTERN
[i
])
66 traffic_type
= DEFAULT_TRAFFIC
;
68 // test for hstop3g traffic -- end
70 traffic_type
= DEFAULT_NOTRAFFIC
;
76 printf("%d:\ttype https\n", sockd
);
80 printf("%d:\ttype ssh\n", sockd
);
84 printf("%d:\ttype hsopt-3g\n", sockd
);
88 printf("%d:\ttype error!\n", sockd
);
92 printf("%d:\tredirect to %s:%d\n", sockd
, host
, *port
);
95 void session_forward(int sock_read
, int sock_write
)
98 char* buffer
=(char*) malloc (BUFFSIZE
);
99 while ((l
= recv(sock_read
, buffer
, BUFFSIZE
, 0)))
101 send(sock_write
, buffer
, l
, 0);
106 void session_start(int sockd
)
110 char* buffer
=(char*) malloc (BUFFSIZE
);
111 session_get_type(sockd
, &port
, buffer
, BUFFSIZE
, &l
);
112 int sockc
= socket(AF_INET
, SOCK_STREAM
, 0);
113 struct sockaddr_in clientaddr
;
114 clientaddr
.sin_family
= AF_INET
;
115 clientaddr
.sin_addr
.s_addr
= inet_addr(host
);
116 clientaddr
.sin_port
= htons(port
);
117 if (connect(sockc
,(struct sockaddr
*) &clientaddr
, sizeof(struct sockaddr_in
)) < 0)
119 perror("\nerror connecting to target\n");
124 send(sockc
, buffer
, l
, 0);
126 if ((cpid
= fork()) == 0) // child: read
128 session_forward(sockd
, sockc
);
130 session_forward(sockc
, sockd
);
132 shutdown(sockc
, SHUT_RDWR
);
133 shutdown(sockd
, SHUT_RDWR
);
134 wait(NULL
); // wait for child above
135 close(sockc
); // close sockets
138 printf("connection closed: %d\n", sockd
);
140 exit(EXIT_SUCCESS
); // exit forked process