Browse files

halbes passv

  • Loading branch information...
1 parent c0be80b commit f9d866ee11170b56d3c47af63399d02f4a0fa986 @grobie committed Jun 11, 2009
Showing with 103 additions and 48 deletions.
  1. +103 −48 duoit.c
View
151 duoit.c
@@ -153,7 +153,7 @@ int append_user(int newfd, usr *user) {
/*
* find user by c_socket number
*/
-int find_user(int socket, usr *head, usr **result) {
+int find_user_by_csocket(int socket, usr *head, usr **result) {
while (head) {
if (head->c_socket == socket) {
*result = head;
@@ -166,6 +166,21 @@ int find_user(int socket, usr *head, usr **result) {
}
/*
+ * find user by d_socket number
+ */
+int find_user_by_dsocket(int socket, usr *head, usr **result) {
+ while (head) {
+ if (head->d_socket == socket) {
+ *result = head;
+ return 0;
+ }
+ head = head->next;
+ }
+
+ return 1;
+}
+
+/*
* find ancestor of user with c_socket number socket
*/
int find_pre_user(int socket, usr *head, usr **result) {
@@ -222,6 +237,41 @@ void handle_new_connection(int *listener, fd_set *master, int *fdmax, usr **user
}
}
+/*
+ * handle new data connection
+ */
+int handle_data_connection(int lsocket, fd_set *master, int *fdmax, usr *head) {
+ struct sockaddr_storage remoteaddr;
+ socklen_t addrlen = sizeof remoteaddr;
+ int newfd; // newly accept()ed socket descriptor
+ usr *user;
+
+ printf("opening passive data connection\n");
+
+ // find user
+ if (find_user_by_dsocket(lsocket, head, &user)) {
+ printf("TODO error");
+ return 1;
+ }
+
+ newfd = accept(lsocket, (struct sockaddr *)&remoteaddr, &addrlen);
+ if (newfd == -1) {
+ perror("accept");
+ } else {
+ FD_SET(newfd, master); // add to master set
+ if (newfd > *fdmax) { // keep track of the max
+ *fdmax = newfd;
+ }
+ close(lsocket);
+ FD_CLR(lsocket, master);
+ }
+
+ user->d_socket = newfd;
+ //user is in passive mode
+ user->passv = 1;
+
+ return 0;
+}
/*
* close connection and remove it from the file discriptors list
@@ -230,7 +280,7 @@ void close_connection(int socket, fd_set *master, usr **head) {
usr *user;
usr *save;
- find_user(socket, *head, &user);
+ find_user_by_csocket(socket, *head, &user);
if (user == *head) {
//remove user-list head
*head = user->next;
@@ -419,7 +469,8 @@ int list_command(instruc *instruction, usr *user) {
char port[5];
int yes=1, rv;
- if (user->d_socket != 0) {
+ if (user->passv == 1) {
+ sock_fd = user->d_socket;
send_message(user->c_socket, "125 Data connection already open; transfer starting.");
} else {
memset(&hints, 0, sizeof hints);
@@ -457,8 +508,8 @@ int list_command(instruc *instruction, usr *user) {
}
}
- send_message(user->d_socket, "total 0\r\ndrwx------+ 24 Grobie staff 816 10 Jun 00:46 Desktop");
- close(user->d_socket);
+ send_message(sock_fd, "total 0\r\ndrwx------+ 24 Grobie staff 816 10 Jun 00:46 Desktop");
+ close(sock_fd);
send_message(user->c_socket, "226 Transfer complete.");
return 0;
}
@@ -467,59 +518,63 @@ int list_command(instruc *instruction, usr *user) {
* sets mode to passive and prepares d_socket for listening
*/
int passv_command(instruc *instruction, usr *user) {
- char reply[26 + 18 + 7]; //#chars of standard reply + ip + #,
+ char reply[30 + 18 + 7]; //#chars of standard reply + ip + #,
char ipstr[INET6_ADDRSTRLEN] = LISTENIP;
char port1[4];
char port2[4];
+ char possible_port[5];
char *ptr;
- int mod, div, i;
+ int mod, div, i, h;
int sock_fd;
struct addrinfo hints, *servinfo, *p;
int yes=1, rv;
- // memset(ipstr, '\0', sizeof ipstr);
- // memset(port1, '\0', sizeof port1);
- // memset(port2, '\0', sizeof port2);
- // memset(reply, '\0', sizeof reply);
+ memset(port1, '\0', sizeof port1);
+ memset(port2, '\0', sizeof port2);
+ memset(possible_port, '\0', sizeof port1);
+ memset(reply, '\0', sizeof reply);
//Create new d_socket we will listen on
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET; //PASV command only definded for IPv4
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; //use own IP
- if ((rv = getaddrinfo(NULL, DPORT, &hints, &servinfo)) != 0) {
- fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
- return 1;
- }
-
- // loop through all the results and bind to the first we can
- for(p = servinfo; p != NULL; p = p->ai_next){
- if ((sock_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
- perror("server: socket");
- continue;
+ for(h = 3022; h < 65535; h++) {
+ sprintf(possible_port, "%d", h);
+ if ((rv = getaddrinfo(NULL, possible_port, &hints, &servinfo)) != 0) {
+ fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
+ return 1;
}
- // reuse sockets
- if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
- perror("setsockopt");
- return 1;
+ // loop through all the results and bind to the first we can
+ for(p = servinfo; p != NULL; p = p->ai_next) {
+ if ((sock_fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1){
+ perror("server: socket");
+ continue;
+ }
+
+ // reuse sockets
+ if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1){
+ perror("setsockopt");
+ return 1;
+ }
+
+ if (bind(sock_fd, p->ai_addr, p->ai_addrlen) == -1){
+ close(sock_fd);
+ perror("server: bind");
+ continue;
+ }
+ break;
}
- if (bind(sock_fd, p->ai_addr, p->ai_addrlen) == -1){
+ if (p == NULL) {
close(sock_fd);
- perror("server: bind");
continue;
}
break;
}
-
- if (p == NULL) {
- fprintf(stderr, "server: failed to bind to DPORT\n");
- return 1;
- }
-
//save our IP-Address
//inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr), ipstr, sizeof ipstr);
@@ -528,15 +583,14 @@ int passv_command(instruc *instruction, usr *user) {
//listen
if (listen(sock_fd, BACKLOG) == -1){
perror("listen");
- exit(1);
+ return 1;
}
- printf("server: waiting for data-connections (port %s) ...\n", DPORT);
+ printf("server: waiting for data-connections (port %s) ...\n", possible_port);
//generating reply for client
strcpy(reply, "227 Entering Passive Mode ");
strcat(reply, "(");
- printf("+++IP: %s\n", ipstr);
//format IP-Adress - e.g. 127,0,0,1
ptr = strtok(ipstr, ".");
while(ptr != NULL) {
@@ -551,20 +605,17 @@ int passv_command(instruc *instruction, usr *user) {
}
//determine formatted port
- div = atoi(DPORT) / 256;
- mod = atoi(DPORT) % 256;
+ div = atoi(possible_port) / 256;
+ mod = atoi(possible_port) % 256;
sprintf(port1, "%d", div);
sprintf(port2, "%d", mod);
//append port
strcat(reply, port1 );
strcat(reply, ",");
strcat(reply, port2);
- strcat(reply, ")");
- printf ("reply: %s\n", reply);
+ strcat(reply, ").");
- //user is in passive mode
- user->passv = 1;
send_message(user->c_socket, reply);
return 0;
}
@@ -742,7 +793,7 @@ int main(int argc, char *argv[]) {
fd_set read_fds; // temp file descriptor list for select()
int fdmax; // maximum file descriptor number
int listener; // listening socket descriptor
- usr *head=NULL;
+ usr *head = NULL;
usr *current_user = NULL;
int i, nbytes;
char buf[256];
@@ -783,12 +834,16 @@ int main(int argc, char *argv[]) {
}
close_connection(i, &master, &head);
} else {
- // client sends message
- if (find_user(i, head, &current_user)) {
- printf("*ERR* corresponding user to socket %d not found!\n", i);
- continue;
+ if (find_user_by_dsocket(i, head, &current_user)) {
+ // client sends message
+ if (find_user_by_csocket(i, head, &current_user)) {
+ printf("*ERR* corresponding user to socket %d not found!\n", i);
+ continue;
+ }
+ dispatch(current_user, buf, nbytes, &master, &head);
+ } else {
+ handle_data_connection(i, &master, &fdmax, head);
}
- dispatch(current_user, buf, nbytes, &master, &head);
}
}

0 comments on commit f9d866e

Please sign in to comment.