Masanobu Yasui authored on 2008/10/06 17:57:47
Showing 8 changed files
... ...
@@ -230,7 +230,7 @@ mhost *member_add(struct in_addr *addr, mdata *data)
230 230
     t->hostname[0] = 0;
231 231
   }
232 232
   if(data){
233
-    if(data->head.opcode == MAKUO_OP_PING || data->head.opcode == MAKUO_OP_PONG){
233
+    if(data->head.opcode == MAKUO_OP_PING){
234 234
       p = (mping *)data->data;
235 235
       l = ntohs(p->hostnamelen);
236 236
       data->p = p->data;
... ...
@@ -1,4 +1,4 @@
1
-「プロトコルフォーマット」
1
+「プロトコルフォーマット(Ver3)」
2 2
 
3 3
  0                   1                   2                   3
4 4
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
... ...
@@ -19,12 +19,13 @@
19 19
 |                                                               | 
20 20
 |                                                               | 
21 21
 |                             data                              | makuo data
22
-|                                                               | 
22
+|                        (MAX 1024Bytes)                        | 
23 23
 |                                                               | 
24 24
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--------------
25 25
 
26
-先頭に32バイトのヘッダ(まくおヘッダ)があり、そのあとに可変長データが続きます。
27
-データ最大サイズは1024バイトです。
26
+先頭に32バイトのヘッダがあります。
27
+そのあとに可変長データが入ります。
28
+データフィールドの最大サイズは1024バイトです。
28 29
 データフォーマットは OperationCode毎に定義します。
29 30
 まくおヘッダの各フィールドの意味は以下の通りです。
30 31
 
... ...
@@ -34,23 +35,27 @@
34 34
 
35 35
 - Operation
36 36
  オペレーションコード
37
+  MAKUO_OP_PING: 
38
+  MAKUO_OP_EXIT:
39
+  MAKUO_OP_FILE:
40
+  MAKUO_OP_MD5 :
37 41
 
38
-- rid
42
+- RequestID
39 43
  コマンドを発行する度にインクリメントする
40 44
 
41 45
 - status
42 46
  現在の状態
43 47
 
44 48
 - old status
45
- さっきの状態
49
+ 以前の状態
46 50
 
47 51
 - data size
48 52
  データフィールドのバイト数
49 53
 
50 54
 - flags
51 55
  bit
52
-  0: データ部が暗号化されている場合は1
53
-  1:
56
+  0: ACKなら1
57
+  1: データ部が暗号化されている場合は1
54 58
   2:
55 59
 
56 60
 - Sequence Number
... ...
@@ -60,8 +65,8 @@
60 60
 
61 61
 [ping]
62 62
 プログラム起動時に送出するパケット。
63
-このパケットを受け取ったノードは送信者をメンバリストに追加してユニキャストで
64
-PONGを返す。
63
+このパケットを受け取ったノードは、送信ノードをメンバリストに追加する。
64
+さらに、ユニキャストでPONGを返す。
65 65
 
66 66
  0                   1                   2                   3
67 67
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
... ...
@@ -81,27 +86,6 @@ HostName:
81 81
 
82 82
 Version String:
83 83
 
84
-[pong]
85
-pingに対する応答パケット。
86
-これを受け取ったノードは送信者をメンバリストに追加する。
87
-また、一定時間(MAKUO_PONG_INTERVAL)毎にマルチキャストして生存確認をする。
88
-MAKUO_PONG_TIMEOUTの間pongを確認できないノードはメンバリストから削除される。
89
-
90
- 0                   1                   2                   3
91
- 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
92
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--------------
93
-|       HostName Length         |     Version String Length     | 
94
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
95
-|                                                               | 
96
-|                          HostName                             | 
97
-|                                                               | 
98
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
99
-|                                                               | 
100
-|                       Version String                          | 
101
-|                                                               | 
102
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+--------------
103
-
104
-
105 84
 [exit]
106 85
 プログラム終了時に発行するパケット。
107 86
 受け取ったノードは送信者をメンバリストから削除する。
... ...
@@ -15,7 +15,7 @@ void usage()
15 15
   printf("  -b dir   # base dir\n");
16 16
   printf("  -p port  # port number       (default: 5000)\n");
17 17
   printf("  -m addr  # multicast address (default: 224.0.0.108)\n");
18
-  printf("  -l addr  # listen address    (default: 0.0.0.0)\n");
18
+  printf("  -l addr  # listen address    (default: 127.0.0.1)\n");
19 19
   printf("  -U path  # unix domain socket\n");
20 20
   printf("  -k file  # key file (encrypt password)\n");
21 21
   printf("  -K file  # key file (console password)\n");
... ...
@@ -24,6 +24,7 @@ void usage()
24 24
   printf("  -r       # don't recv\n");
25 25
   printf("  -s       # don't send\n");
26 26
   printf("  -o       # don't listen (console off mode)\n");
27
+  printf("  -O       # owner match limitation mode\n");
27 28
   printf("  -h       # help\n\n"); 
28 29
   exit(0);
29 30
 }
... ...
@@ -99,7 +100,7 @@ struct timeval *pingpong(int n)
99 99
   static struct timeval tv;
100 100
   mfile *m = mfins(0);
101 101
   mping *p = NULL;
102
-  char buff[HOST_NAME_MAX + 1];
102
+  char buff[MAKUO_HOSTNAME_MAX + 1];
103 103
 
104 104
   if(!m){
105 105
     lprintf(0, "pingpong: out of memmory\r\n");
... ...
@@ -110,7 +111,8 @@ struct timeval *pingpong(int n)
110 110
       m->mdata.head.opcode = MAKUO_OP_PING;
111 111
       break;
112 112
     case 1:
113
-      m->mdata.head.opcode = MAKUO_OP_PONG;
113
+      m->mdata.head.opcode = MAKUO_OP_PING;
114
+      m->mdata.head.flags |= MAKUO_FLAG_ACK;
114 115
       break;
115 116
     case 2:
116 117
       m->mdata.head.opcode = MAKUO_OP_EXIT;
... ...
@@ -2,7 +2,7 @@
2 2
  * [MAKUOSAN]
3 3
  *  multicast file synchronization system
4 4
  */
5
-#define MAKUOSAN_VERSION "0.8.5"
5
+#define MAKUOSAN_VERSION "0.8.6"
6 6
 #define PROTOCOL_VERSION 3
7 7
 #define _GNU_SOURCE
8 8
 #define _FILE_OFFSET_BITS 64
... ...
@@ -38,8 +38,9 @@
38 38
 #include <openssl/blowfish.h>
39 39
 
40 40
 /*----- limit -----*/
41
-#define MAX_COMM          8
41
+#define MAX_COMM             8
42 42
 #define MAKUO_BUFFER_SIZE 1024
43
+#define MAKUO_HOSTNAME_MAX 255
43 44
 
44 45
 /*----- default -----*/
45 46
 #define MAKUO_LOCAL_ADDR  "127.0.0.1"
... ...
@@ -47,22 +48,21 @@
47 47
 #define MAKUO_MCAST_PORT  5000
48 48
 
49 49
 /*----- timeout -----*/
50
-#define MAKUO_SEND_TIMEOUT  500     /* 再送間隔(ms)                     */
51
-#define MAKUO_SEND_RETRYCNT 120     /* 再送回数                         */
52
-#define MAKUO_PONG_TIMEOUT  180000  /* メンバから除外するまでの時間(ms) */
53
-#define MAKUO_PONG_INTERVAL 45000   /* PING送信間隔(ms)                 */
50
+#define MAKUO_SEND_TIMEOUT  500    /* 再送間隔(ms)                     */
51
+#define MAKUO_SEND_RETRYCNT 120    /* 再送回数                         */
52
+#define MAKUO_PONG_TIMEOUT  180000 /* メンバから除外するまでの時間(ms) */
53
+#define MAKUO_PONG_INTERVAL 45000  /* PING送信間隔(ms)                 */
54 54
 #define MAKUO_RECV_GCWAIT   300000
55 55
 
56 56
 /*----- operation -----*/
57 57
 #define MAKUO_OP_PING 0
58
-#define MAKUO_OP_PONG 1
59
-#define MAKUO_OP_EXIT 2
60
-#define MAKUO_OP_ACK  3
61
-#define MAKUO_OP_FILE 4
62
-#define MAKUO_OP_MD5  5
58
+#define MAKUO_OP_EXIT 1
59
+#define MAKUO_OP_FILE 2
60
+#define MAKUO_OP_MD5  3
63 61
 
64 62
 /*----- flags -----*/
65
-#define MAKUO_FLAG_CRYPT 1
63
+#define MAKUO_FLAG_ACK   1
64
+#define MAKUO_FLAG_CRYPT 2
66 65
 
67 66
 /*----- sendstatus -----*/
68 67
 #define MAKUO_SENDSTATE_STAT       0
... ...
@@ -196,7 +196,7 @@ typedef struct
196 196
 typedef struct
197 197
 {
198 198
   int state;
199
-  char hostname[HOST_NAME_MAX];
199
+  char hostname[MAKUO_HOSTNAME_MAX];
200 200
   char version[32];
201 201
   struct in_addr ad;
202 202
   struct timeval lastrecv;
... ...
@@ -216,6 +216,7 @@ typedef struct
216 216
   int cryptena;
217 217
   int comm_ena;
218 218
   int commpass;
219
+  int ownmatch;
219 220
   struct sockaddr_in maddr;
220 221
   struct sockaddr_in laddr;
221 222
   struct sockaddr_un uaddr;
... ...
@@ -49,6 +49,7 @@ static void minit_option_setdefault()
49 49
   moption.cryptena              = 0;
50 50
   moption.comm_ena              = 1;
51 51
   moption.commpass              = 0;
52
+  moption.ownmatch              = 0;
52 53
   moption.chroot                = 0;
53 54
   moption.uid                   = geteuid();
54 55
   moption.gid                   = getegid();
... ...
@@ -251,6 +252,10 @@ static void minit_getopt(int argc, char *argv[])
251 251
         minit_password(optarg, 1);
252 252
         break;
253 253
 
254
+      case 'O':
255
+        moption.ownmatch = 1;
256
+        break;
257
+
254 258
       case '?':
255 259
         exit(1);
256 260
     }
... ...
@@ -429,18 +434,19 @@ static void minit_bootlog()
429 429
   lprintf(0,"makuosan version %s\n",MAKUOSAN_VERSION);
430 430
   lprintf(0,"loglevel  : %d\n", moption.loglevel);
431 431
 if(moption.chroot)
432
-  lprintf(0,"chroot    : %s\n", moption.real_dir);
433
-  lprintf(0,"base dir  : %s\n", moption.base_dir);
434
-  lprintf(0,"multicast : %s\n", inet_ntoa(moption.maddr.sin_addr));
435
-  lprintf(0,"port      : %d\n", ntohs(moption.maddr.sin_port));
436
-  lprintf(0,"uid       : %d\n", geteuid());
437
-  lprintf(0,"gid       : %d\n", getegid());
438
-  lprintf(0,"don't recv: %s\n", yesno[moption.dontrecv]);
439
-  lprintf(0,"don't send: %s\n", yesno[moption.dontsend]);
440
-  lprintf(0,"don't fork: %s\n", yesno[moption.dontfork]);
441
-  lprintf(0,"encrypt   : %s\n", yesno[moption.cryptena]);
442
-  lprintf(0,"console   : %s\n", yesno[moption.comm_ena]);
443
-  lprintf(0,"passwoed  : %s\n", yesno[moption.commpass]);
432
+  lprintf(0,"chroot     : %s\n", moption.real_dir);
433
+  lprintf(0,"base dir   : %s\n", moption.base_dir);
434
+  lprintf(0,"multicast  : %s\n", inet_ntoa(moption.maddr.sin_addr));
435
+  lprintf(0,"port       : %d\n", ntohs(moption.maddr.sin_port));
436
+  lprintf(0,"uid        : %d\n", geteuid());
437
+  lprintf(0,"gid        : %d\n", getegid());
438
+  lprintf(0,"don't recv : %s\n", yesno[moption.dontrecv]);
439
+  lprintf(0,"don't send : %s\n", yesno[moption.dontsend]);
440
+  lprintf(0,"don't fork : %s\n", yesno[moption.dontfork]);
441
+  lprintf(0,"encrypt    : %s\n", yesno[moption.cryptena]);
442
+  lprintf(0,"console    : %s\n", yesno[moption.comm_ena]);
443
+  lprintf(0,"passwoed   : %s\n", yesno[moption.commpass]);
444
+  lprintf(0,"owner match: %s\n", yesno[moption.ownmatch]);
444 445
   if(moption.comm_ena){
445 446
     if(moption.uaddr.sun_path[0]){
446 447
       lprintf(0,"listen    : %s\n", moption.uaddr.sun_path);
... ...
@@ -1,12 +1,13 @@
1
-/*
2
- *  mrecv.c
3
- */
4 1
 #include "makuosan.h"
5 2
 
6
-/*
7
- * mfile を開放する
8
- * mrecv.c の中で生成した mfile は必ずここで開放すること
9
- */
3
+static void mrecv_req(mdata *data, struct sockaddr_in *addr);
4
+static void mrecv_ack(mdata *data, struct sockaddr_in *addr);
5
+
6
+/******************************************************************
7
+*
8
+* Receive common functions (private)
9
+*
10
+*******************************************************************/
10 11
 static mfile *mrecv_mfdel(mfile *m)
11 12
 {
12 13
   mfile *r;
... ...
@@ -27,20 +28,257 @@ static mfile *mrecv_mfdel(mfile *m)
27 27
   return(r);
28 28
 }
29 29
 
30
-static void mrecv_ping(mdata *data, struct sockaddr_in *addr)
30
+static int mrecv_decrypt(mdata *data, struct sockaddr_in *addr)
31
+{
32
+  int i;
33
+  MD5_CTX ctx;
34
+  uint8_t hash[16];
35
+
36
+  if(data->head.flags & MAKUO_FLAG_CRYPT){
37
+    if(!moption.cryptena){
38
+      lprintf(0, "mrecv_decrypt: recv encrypt packet from %s. I have not key!", inet_ntoa(addr->sin_addr));
39
+      return(-1);
40
+    }
41
+    if(data->head.szdata){
42
+      for(i=0;i<data->head.szdata;i+=8){
43
+        BF_decrypt((BF_LONG *)(data->data + i), &EncKey);
44
+      }
45
+      MD5_Init(&ctx);
46
+      MD5_Update(&ctx, data->data, data->head.szdata);
47
+      MD5_Final(hash, &ctx);
48
+      if(memcmp(hash,data->head.hash,16)){
49
+        lprintf(0, "mrecv_decrypt: protocol checksum error from %s\n", inet_ntoa(addr->sin_addr));
50
+        return(-1);
51
+      }
52
+    }
53
+  }
54
+  return(0);
55
+}
56
+
57
+static int mrecv_packet(int s, mdata *data, struct sockaddr_in *addr)
58
+{
59
+  int recvsize;
60
+  socklen_t addr_len;
61
+
62
+  while(1){
63
+    addr_len = sizeof(struct sockaddr_in);
64
+    recvsize = recvfrom(s, data, sizeof(mdata), 0, (struct sockaddr *)addr, &addr_len);
65
+    if(recvsize != -1){
66
+      break;
67
+    }else{
68
+      if(errno == EAGAIN || errno == EINTR){
69
+        continue;
70
+      }else{
71
+        lprintf(0, "mrecv_packets: recv error from %s\n", inet_ntoa(addr->sin_addr));
72
+        return(-1);
73
+      }
74
+    }
75
+  }
76
+  if(recvsize < sizeof(data->head)){
77
+    lprintf(0, "mrecv: recv head size error\n");
78
+    return(-1);
79
+  }
80
+
81
+  data->head.szdata = ntohs(data->head.szdata);
82
+  data->head.flags  = ntohs(data->head.flags);
83
+  data->head.reqid  = ntohl(data->head.reqid);
84
+  data->head.seqno  = ntohl(data->head.seqno);
85
+
86
+  if(data->head.vproto != PROTOCOL_VERSION){
87
+    lprintf(0, "mrecv_packet: protocol version error(%d != %d) from %s\n",
88
+       data->head.vproto, PROTOCOL_VERSION, inet_ntoa(addr->sin_addr));
89
+    return(-1);
90
+  }
91
+
92
+  return(mrecv_decrypt(data, addr));
93
+}
94
+
95
+/******************************************************************
96
+*
97
+* Receive common functions (public)
98
+*
99
+*******************************************************************/
100
+void mrecv(int s)
101
+{
102
+  mdata  data;
103
+  struct sockaddr_in addr;
104
+  if(mrecv_packet(s, &data, &addr) == -1){
105
+    return;
106
+  }
107
+  if(data.head.flags & MAKUO_FLAG_ACK){
108
+    mrecv_ack(&data, &addr);
109
+  }else{
110
+    mrecv_req(&data, &addr);
111
+  }
112
+}
113
+
114
+void mrecv_gc()
115
+{
116
+  mhost *t = members;
117
+  mfile *m = mftop[1]; 
118
+
119
+  /* file timeout */
120
+  while(m){
121
+    if(mtimeout(&(m->lastrecv), MAKUO_RECV_GCWAIT)){
122
+      lprintf(0,"mrecv_gc: mfile object GC state=%d %s\n", m->mdata.head.nstate, m->fn);
123
+      m = mrecv_mfdel(m);
124
+      continue;
125
+    }
126
+    m = m->next;
127
+  }
128
+
129
+  /* pong timeout */
130
+  while(t){
131
+    if(!mtimeout(&(t->lastrecv), MAKUO_PONG_TIMEOUT)){
132
+      t = t->next;
133
+    }else{
134
+      lprintf(0,"mrecv_gc: pong timeout %s\n", t->hostname);
135
+      if(t->next){
136
+        t = t->next;
137
+        member_del(t->prev);
138
+      }else{
139
+        member_del(t);
140
+        t = NULL;
141
+     } 
142
+    }      
143
+  }
144
+}
145
+
146
+/******************************************************************
147
+*
148
+* ack receive functions (for server tasks)
149
+*
150
+*******************************************************************/
151
+static void mrecv_ack_search(mhost **lpt, mfile **lpm, mdata *data, struct sockaddr_in *addr)
152
+{
153
+  mhost *t;
154
+  mfile *m;
155
+  *lpt = NULL;
156
+  *lpm = NULL;
157
+  t = member_add(&addr->sin_addr, NULL);
158
+  if(!t){
159
+    lprintf(0, "mrecv_ack: member not found %s\n", inet_ntoa(addr->sin_addr));
160
+    return;
161
+  }
162
+  for(m=mftop[0];m;m=m->next)
163
+    if(m->mdata.head.reqid == data->head.reqid)
164
+      break;
165
+  if(!m){
166
+    lprintf(4, "mrecv_ack: mfile not found rid=%06d state=%02d %s(%s)\n", 
167
+      data->head.reqid, data->head.nstate, inet_ntoa(addr->sin_addr), t->hostname);
168
+    return;
169
+  }
170
+  *lpt = t;
171
+  *lpm = m;
172
+}
173
+
174
+static void mrecv_ack_report(mfile *m, mhost *h, mdata *data)
175
+{
176
+  if(data->head.nstate == MAKUO_RECVSTATE_OPENERROR){
177
+    cprintf(0, m->comm, "%s: file open error %s\n", h->hostname, m->fn);
178
+    lprintf(0,          "mrecv_ack: file open error rid=%06d state=%02d %s(%s) %s\n", 
179
+      data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
180
+  }
181
+  if(data->head.nstate == MAKUO_RECVSTATE_WRITEERROR){
182
+    cprintf(0, m->comm, "%s: file write error %s\n", h->hostname, m->fn);
183
+    lprintf(0,          "mrecv_ack: file write error rid=%06d state=%02d %s(%s) %s\n", 
184
+     data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
185
+  }
186
+  if(data->head.nstate == MAKUO_RECVSTATE_CLOSEERROR){
187
+    cprintf(0, m->comm, "%s: file close error %s\n", h->hostname, m->fn);
188
+    lprintf(0,          "mrecv_ack: file close error rid=%06d state=%02d %s(%s) %s\n", 
189
+      data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
190
+  }
191
+}
192
+
193
+static void mrecv_ack_ping(mdata *data, struct sockaddr_in *addr)
194
+{
195
+  member_add(&addr->sin_addr, data);
196
+}
197
+
198
+static void mrecv_ack_file(mdata *data, struct sockaddr_in *addr)
199
+{
200
+  mhost *t;
201
+  mfile *m;
202
+
203
+  mrecv_ack_search(&t, &m, data, addr);
204
+  mtimeget(&m->lastrecv);
205
+  if(data->head.nstate == MAKUO_RECVSTATE_IGNORE){
206
+    cprintf(4, m->comm, "%s: file update ignore %s\n", t->hostname, m->fn);
207
+    lprintf(0,          "mrecv_ack: file update ignore rid=%06d state=%02d %s(%s) %s\n", 
208
+      data->head.reqid, data->head.nstate, inet_ntoa(t->ad), t->hostname, m->fn);
209
+  }
210
+  if(data->head.nstate == MAKUO_RECVSTATE_OPEN){
211
+    uint32_t *d = (uint32_t *)(data->data);
212
+    while(d < (uint32_t *)&data->data[data->head.szdata]){
213
+      seq_addmark(m, *d, (*d) + 1);
214
+      d++;
215
+    }
216
+  }
217
+  t->state = data->head.nstate;
218
+  mrecv_ack_report(m, t, data);
219
+}
220
+
221
+static void mrecv_ack_md5(mdata *data, struct sockaddr_in *addr)
222
+{
223
+  mhost *t;
224
+  mfile *m;
225
+
226
+  mrecv_ack_search(&t, &m, data, addr);
227
+  if(!t || !m){
228
+    return;
229
+  }
230
+  mtimeget(&m->lastrecv);
231
+  if(t->state != data->head.nstate){
232
+    if(data->head.nstate == MAKUO_RECVSTATE_MD5OK){
233
+      cprintf(1, m->comm, "%s: OK %s\r\n", t->hostname, m->fn);
234
+      lprintf(1,          "mrecv_ack_md5: OK %s\n", m->fn);
235
+    }
236
+    if(data->head.nstate == MAKUO_RECVSTATE_MD5NG){
237
+      cprintf(0, m->comm, "%s: NG %s\r\n", t->hostname, m->fn);
238
+      lprintf(0,          "mrecv_ack_md5: NG %s\n", m->fn);
239
+    }
240
+  }
241
+  t->state = data->head.nstate;
242
+  mrecv_ack_report(m, t, data);
243
+}
244
+
245
+static void mrecv_ack(mdata *data, struct sockaddr_in *addr)
246
+{
247
+  switch(data->head.opcode){
248
+    case MAKUO_OP_PING:
249
+      mrecv_ack_ping(data, addr);
250
+      break;
251
+    case MAKUO_OP_FILE:
252
+      mrecv_ack_file(data, addr);
253
+      break;
254
+    case MAKUO_OP_MD5:
255
+      mrecv_ack_md5(data, addr);
256
+      break;
257
+  }
258
+}
259
+
260
+/******************************************************************
261
+*
262
+* Request receive functions (for client tasks)
263
+*
264
+*******************************************************************/
265
+static void mrecv_req_ping(mdata *data, struct sockaddr_in *addr)
31 266
 {
32 267
   mping *p;
33 268
   mfile *m;
34
-  char buff[HOST_NAME_MAX + 1];
269
+  char buff[MAKUO_HOSTNAME_MAX + 1];
35 270
   member_add(&addr->sin_addr, data);
36 271
   m = mfadd(0);
37 272
   if(!m){
273
+    lprintf(0,"mrecv_req_ping: out of memory\n");
38 274
     return;
39 275
   }
40
-  m->mdata.head.opcode    = MAKUO_OP_PONG;
41
-  m->mdata.head.reqid   = getrid();
42
-  m->mdata.head.seqno = 0;
43
-  m->mdata.head.szdata  = 0;
276
+  m->mdata.head.opcode = MAKUO_OP_PING;
277
+  m->mdata.head.flags |= MAKUO_FLAG_ACK;
278
+  m->mdata.head.reqid  = data->head.reqid;
279
+  m->mdata.head.seqno  = 0;
280
+  m->mdata.head.szdata = 0;
44 281
   memcpy(&(m->addr), addr, sizeof(m->addr));
45 282
   if(gethostname(buff, sizeof(buff)) == -1){
46 283
     buff[0] = 0;
... ...
@@ -58,12 +296,7 @@ static void mrecv_ping(mdata *data, struct sockaddr_in *addr)
58 58
   p->versionlen  = htons(p->versionlen);
59 59
 }
60 60
 
61
-static void mrecv_pong(mdata *data, struct sockaddr_in *addr)
62
-{
63
-  member_add(&addr->sin_addr, data);
64
-}
65
-
66
-static void mrecv_exit(mdata *data, struct sockaddr_in *addr)
61
+static void mrecv_req_exit(mdata *data, struct sockaddr_in *addr)
67 62
 {
68 63
   mhost *h;
69 64
   for(h=members;h;h=h->next)
... ...
@@ -75,7 +308,7 @@ static void mrecv_exit(mdata *data, struct sockaddr_in *addr)
75 75
 /*
76 76
  *  データ受信
77 77
  */
78
-static int mrecv_file_data(mfile *m,  mdata *r)
78
+static int mrecv_req_file_data(mfile *m,  mdata *r)
79 79
 {
80 80
   if(m->mdata.head.nstate != MAKUO_RECVSTATE_OPEN)
81 81
     return(0);
... ...
@@ -112,7 +345,7 @@ static int mrecv_file_data(mfile *m,  mdata *r)
112 112
 /*
113 113
  *  転送中断
114 114
  */
115
-static int mrecv_file_break(mfile *m, mdata *r)
115
+static int mrecv_req_file_break(mfile *m, mdata *r)
116 116
 {
117 117
   mrecv_mfdel(m);
118 118
   return(0);
... ...
@@ -121,7 +354,7 @@ static int mrecv_file_break(mfile *m, mdata *r)
121 121
 /*
122 122
  *  転送開始処理
123 123
  */
124
-static int mrecv_file_open(mfile *m, mdata *r)
124
+static int mrecv_req_file_open(mfile *m, mdata *r)
125 125
 {
126 126
   char fpath[PATH_MAX];
127 127
   char tpath[PATH_MAX];
... ...
@@ -133,9 +366,10 @@ static int mrecv_file_open(mfile *m, mdata *r)
133 133
   sprintf(tpath, "%s/%s", moption.base_dir, m->tn);
134 134
 
135 135
   mfile *a = mfins(0);
136
-  a->mdata.head.opcode = MAKUO_OP_ACK;
137
-  a->mdata.head.reqid = r->head.reqid;
138
-  a->mdata.head.seqno = r->head.seqno;
136
+  a->mdata.head.flags |= MAKUO_FLAG_ACK;
137
+  a->mdata.head.opcode = r->head.opcode;
138
+  a->mdata.head.reqid  = r->head.reqid;
139
+  a->mdata.head.seqno  = r->head.seqno;
139 140
   a->mdata.head.ostate = m->mdata.head.nstate;
140 141
   a->mdata.head.nstate = MAKUO_RECVSTATE_OPEN;
141 142
   m->mdata.head.nstate = MAKUO_RECVSTATE_OPEN;
... ...
@@ -181,7 +415,7 @@ static int mrecv_file_open(mfile *m, mdata *r)
181 181
 /*
182 182
  *  転送終了処理
183 183
  */
184
-static int mrecv_file_close(mfile *m, mdata *r)
184
+static int mrecv_req_file_close(mfile *m, mdata *r)
185 185
 {
186 186
   struct utimbuf mftime;
187 187
   char  fpath[PATH_MAX];
... ...
@@ -192,9 +426,10 @@ static int mrecv_file_close(mfile *m, mdata *r)
192 192
   if(m->mdata.head.nstate == MAKUO_RECVSTATE_OPEN  ||
193 193
      m->mdata.head.nstate == MAKUO_RECVSTATE_UPDATE){
194 194
     mfile *a = mfins(0);
195
-    a->mdata.head.opcode = MAKUO_OP_ACK;
196
-    a->mdata.head.reqid = r->head.reqid;
197
-    a->mdata.head.seqno = r->head.seqno;
195
+    a->mdata.head.flags |= MAKUO_FLAG_ACK;
196
+    a->mdata.head.opcode = r->head.opcode;
197
+    a->mdata.head.reqid  = r->head.reqid;
198
+    a->mdata.head.seqno  = r->head.seqno;
198 199
     a->mdata.head.ostate = m->mdata.head.nstate;
199 200
     a->mdata.head.nstate = MAKUO_RECVSTATE_CLOSE;
200 201
     memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
... ...
@@ -247,17 +482,18 @@ static int mrecv_file_close(mfile *m, mdata *r)
247 247
 /*
248 248
  *  再送要求
249 249
  */
250
-static int mrecv_file_mark(mfile *m, mdata *r)
250
+static int mrecv_req_file_mark(mfile *m, mdata *r)
251 251
 {
252 252
   if(m->mdata.head.nstate != MAKUO_RECVSTATE_OPEN)
253 253
     return(0);
254 254
 
255 255
   mfile *a = mfins(0);
256
-  a->mdata.head.opcode    = MAKUO_OP_ACK;
257
-  a->mdata.head.reqid   = r->head.reqid;
258
-  a->mdata.head.seqno = r->head.seqno;
256
+  a->mdata.head.flags |= MAKUO_FLAG_ACK;
257
+  a->mdata.head.opcode = r->head.opcode;
258
+  a->mdata.head.reqid  = r->head.reqid;
259
+  a->mdata.head.seqno  = r->head.seqno;
259 260
   a->mdata.head.nstate = m->mdata.head.nstate;
260
-  a->mdata.head.szdata  = 0;
261
+  a->mdata.head.szdata = 0;
261 262
   memcpy(&(a->addr), &(m->addr), sizeof(a->addr));
262 263
   m->lickflag = 1;
263 264
   a->lickflag = 1;
... ...
@@ -283,25 +519,25 @@ static int mrecv_file_mark(mfile *m, mdata *r)
283 283
  *  受信状態遷移関数
284 284
  *
285 285
  */
286
-static int mrecv_file_next(mfile *m,  mdata *r)
286
+static int mrecv_req_file_next(mfile *m,  mdata *r)
287 287
 {
288 288
   if(r->head.seqno){
289
-    return(mrecv_file_data(m, r));
289
+    return(mrecv_req_file_data(m, r));
290 290
   }
291 291
   switch(r->head.nstate){
292 292
     case MAKUO_SENDSTATE_BREAK:
293 293
       lprintf(9,"mrecv_file: MAKUO_SENDSTATE_BREAK: state=%d %s\n", m->mdata.head.nstate, m->fn);
294
-      return(mrecv_file_break(m, r));
294
+      return(mrecv_req_file_break(m, r));
295 295
     case MAKUO_SENDSTATE_OPEN:
296 296
       lprintf(9,"mrecv_file: MAKUO_SENDSTATE_OPEN : state=%d %s\n", m->mdata.head.nstate, m->fn);
297
-      return(mrecv_file_open(m, r));
297
+      return(mrecv_req_file_open(m, r));
298 298
     case MAKUO_SENDSTATE_MARK:
299 299
       lprintf(9,"mrecv_file: MAKUO_SENDSTATE_MARK : state=%d seqno=%d max=%d cnt=%d %s\n", 
300 300
              m->mdata.head.nstate, m->mdata.head.seqno, m->seqnomax, m->markcount, m->fn);
301
-      return(mrecv_file_mark(m, r));
301
+      return(mrecv_req_file_mark(m, r));
302 302
     case MAKUO_SENDSTATE_CLOSE:
303 303
       lprintf(9,"mrecv_file: MAKUO_SENDSTATE_CLOSE: state=%d %s\n", m->mdata.head.nstate, m->fn);
304
-      return(mrecv_file_close(m, r));
304
+      return(mrecv_req_file_close(m, r));
305 305
   }
306 306
   return(0);
307 307
 }
... ...
@@ -311,7 +547,7 @@ static int mrecv_file_next(mfile *m,  mdata *r)
311 311
  *  - 引数として生データが格納されているバッファのポインタを受け取る
312 312
  *  - 受信したデータが転送開始メッセージならばmfileを生成する
313 313
 */
314
-static mfile *mrecv_file_stat(mdata *data, struct sockaddr_in *addr)
314
+static mfile *mrecv_req_file_stat(mdata *data, struct sockaddr_in *addr)
315 315
 {
316 316
   mstat fs;
317 317
   uint16_t  fnlen;
... ...
@@ -325,10 +561,11 @@ static mfile *mrecv_file_stat(mdata *data, struct sockaddr_in *addr)
325 325
     return(NULL);
326 326
 
327 327
   a = mfins(0);
328
-  a->mdata.head.opcode    = MAKUO_OP_ACK;
329
-  a->mdata.head.reqid   = data->head.reqid;
330
-  a->mdata.head.szdata  = 0;
331
-  a->mdata.head.seqno = data->head.seqno;
328
+  a->mdata.head.flags |= MAKUO_FLAG_ACK;
329
+  a->mdata.head.opcode = data->head.opcode;
330
+  a->mdata.head.reqid  = data->head.reqid;
331
+  a->mdata.head.szdata = 0;
332
+  a->mdata.head.seqno  = data->head.seqno;
332 333
   a->mdata.head.nstate = MAKUO_RECVSTATE_IGNORE;
333 334
   memcpy(&(a->addr), addr, sizeof(a->addr));
334 335
   if(data->head.nstate == MAKUO_SENDSTATE_STAT){
... ...
@@ -385,7 +622,7 @@ static mfile *mrecv_file_stat(mdata *data, struct sockaddr_in *addr)
385 385
   return(m);
386 386
 }
387 387
 
388
-static void mrecv_file(mdata *data, struct sockaddr_in *addr)
388
+static void mrecv_req_file(mdata *data, struct sockaddr_in *addr)
389 389
 {
390 390
   mfile *m = mftop[1]; 
391 391
   while(m){
... ...
@@ -396,95 +633,14 @@ static void mrecv_file(mdata *data, struct sockaddr_in *addr)
396 396
     m = m->next;
397 397
   }
398 398
   if(!m){
399
-    mrecv_file_stat(data, addr);
399
+    mrecv_req_file_stat(data, addr);
400 400
   }else{
401 401
     mtimeget(&(m->lastrecv));
402
-    mrecv_file_next(m, data);
403
-  }
404
-}
405
-
406
-static void mrecv_ack_file(mfile *m, mhost *h, mdata *data)
407
-{
408
-  uint32_t *d;
409
-
410
-  if(data->head.nstate == MAKUO_RECVSTATE_IGNORE){
411
-    cprintf(4, m->comm, "%s: file update ignore %s\n", h->hostname, m->fn);
412
-    lprintf(0,          "mrecv_ack: file update ignore rid=%06d state=%02d %s(%s) %s\n", 
413
-      data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
414
-  }
415
-  if(data->head.nstate == MAKUO_RECVSTATE_OPEN){
416
-    d = (uint32_t *)(data->data);
417
-    while(d < (uint32_t *)&data->data[data->head.szdata]){
418
-      seq_addmark(m, *d, (*d) + 1);
419
-      d++;
420
-    }
402
+    mrecv_req_file_next(m, data);
421 403
   }
422 404
 }
423 405
 
424
-static void mrecv_ack_md5(mfile *m, mhost *h, mdata *data)
425
-{
426
-  if(h->state != data->head.nstate){
427
-    if(data->head.nstate == MAKUO_RECVSTATE_MD5OK){
428
-      cprintf(1, m->comm, "%s: OK %s\r\n", h->hostname, m->fn);
429
-      lprintf(1,          "mrecv_ack_md5: OK %s\n", m->fn);
430
-    }
431
-    if(data->head.nstate == MAKUO_RECVSTATE_MD5NG){
432
-      cprintf(0, m->comm, "%s: NG %s\r\n", h->hostname, m->fn);
433
-      lprintf(0,          "mrecv_ack_md5: NG %s\n", m->fn);
434
-    }
435
-  }
436
-}
437
-
438
-/*
439
- *  ack受信処理
440
- */
441
-static void mrecv_ack(mdata *data, struct sockaddr_in *addr)
442
-{
443
-  mfile *m;
444
-  mhost *h;
445
-
446
-  h = member_add(&addr->sin_addr, NULL);
447
-  if(!h){
448
-    lprintf(0, "mrecv_ack: member not found %s\n", inet_ntoa(addr->sin_addr));
449
-    return;
450
-  }
451
-  for(m=mftop[0];m;m=m->next)
452
-    if(m->mdata.head.reqid == data->head.reqid)
453
-      break;
454
-  if(!m){
455
-    lprintf(4, "mrecv_ack: mfile not found rid=%06d state=%02d %s(%s)\n", 
456
-      data->head.reqid, data->head.nstate, inet_ntoa(addr->sin_addr), h->hostname);
457
-    return;
458
-  }
459
-  mtimeget(&m->lastrecv);
460
-  switch(m->mdata.head.opcode){
461
-    case MAKUO_OP_FILE:
462
-      mrecv_ack_file(m,h,data);
463
-      break;
464
-    case MAKUO_OP_MD5:
465
-      mrecv_ack_md5(m,h,data);
466
-      break;
467
-  }
468
-  if(data->head.nstate == MAKUO_RECVSTATE_OPENERROR){
469
-    cprintf(0, m->comm, "%s: file open error %s\n", h->hostname, m->fn);
470
-    lprintf(0,          "mrecv_ack: file open error rid=%06d state=%02d %s(%s) %s\n", 
471
-      data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
472
-  }
473
-  if(data->head.nstate == MAKUO_RECVSTATE_WRITEERROR){
474
-    cprintf(0, m->comm, "%s: file write error %s\n", h->hostname, m->fn);
475
-    lprintf(0,          "mrecv_ack: file write error rid=%06d state=%02d %s(%s) %s\n", 
476
-     data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
477
-  }
478
-  if(data->head.nstate == MAKUO_RECVSTATE_CLOSEERROR){
479
-    cprintf(0, m->comm, "%s: file close error %s\n", h->hostname, m->fn);
480
-    lprintf(0,          "mrecv_ack: file close error rid=%06d state=%02d %s(%s) %s\n", 
481
-      data->head.reqid, data->head.nstate, inet_ntoa(h->ad), h->hostname, m->fn);
482
-  }
483
-  h->state = data->head.nstate;
484
-  return;
485
-}
486
-
487
-static void mrecv_md5_open(mfile *m, mdata *data, struct sockaddr_in *addr)
406
+static void mrecv_req_md5_open(mfile *m, mdata *data, struct sockaddr_in *addr)
488 407
 {
489 408
   int    r;
490 409
   int    l;
... ...
@@ -519,22 +675,24 @@ static void mrecv_md5_open(mfile *m, mdata *data, struct sockaddr_in *addr)
519 519
     }
520 520
   }
521 521
   a=mfadd(0);
522
-  a->mdata.head.opcode    = MAKUO_OP_ACK;
523
-  a->mdata.head.reqid   = m->mdata.head.reqid;
524
-  a->mdata.head.seqno = 0;
525
-  a->mdata.head.szdata  = 0;
522
+  a->mdata.head.flags |= MAKUO_FLAG_ACK;
523
+  a->mdata.head.opcode = m->mdata.head.opcode;
524
+  a->mdata.head.reqid  = m->mdata.head.reqid;
525
+  a->mdata.head.seqno  = 0;
526
+  a->mdata.head.szdata = 0;
526 527
   a->mdata.head.nstate = m->mdata.head.nstate;
527 528
   memcpy(&(a->addr), addr, sizeof(a->addr));
528 529
   mtimeget(&(m->lastrecv));
529 530
 }
530 531
 
531
-static void mrecv_md5_close(mfile *m, mdata *data, struct sockaddr_in *addr)
532
+static void mrecv_req_md5_close(mfile *m, mdata *data, struct sockaddr_in *addr)
532 533
 {
533 534
   mfile *a = mfadd(0);
534
-  a->mdata.head.opcode    = MAKUO_OP_ACK;
535
-  a->mdata.head.reqid   = data->head.reqid;
536
-  a->mdata.head.szdata  = 0;
537
-  a->mdata.head.seqno = 0;
535
+  a->mdata.head.flags |= MAKUO_FLAG_ACK;
536
+  a->mdata.head.opcode = data->head.opcode;
537
+  a->mdata.head.reqid  = data->head.reqid;
538
+  a->mdata.head.szdata = 0;
539
+  a->mdata.head.seqno  = 0;
538 540
   a->mdata.head.nstate = MAKUO_RECVSTATE_CLOSE;
539 541
   memcpy(&(a->addr), addr, sizeof(a->addr));
540 542
   mrecv_mfdel(m);
... ...
@@ -545,7 +703,7 @@ static void mrecv_md5_close(mfile *m, mdata *data, struct sockaddr_in *addr)
545 545
  * mfileオブジェクトを生成して
546 546
  * 対象ファイルのmd5を取得する
547 547
  */
548
-static void mrecv_md5(mdata *data, struct sockaddr_in *addr)
548
+static void mrecv_req_md5(mdata *data, struct sockaddr_in *addr)
549 549
 {
550 550
   mfile *m = mftop[1];
551 551
   while(m){
... ...
@@ -557,144 +715,28 @@ static void mrecv_md5(mdata *data, struct sockaddr_in *addr)
557 557
   }
558 558
   switch(data->head.nstate){
559 559
     case MAKUO_SENDSTATE_OPEN:
560
-      mrecv_md5_open(m, data, addr);
560
+      mrecv_req_md5_open(m, data, addr);
561 561
       break;
562 562
     case MAKUO_SENDSTATE_CLOSE:
563
-      mrecv_md5_close(m, data, addr);
564
-      break;
565
-  }
566
-}
567
-
568
-static int mrecv_decrypt(mdata *data, struct sockaddr_in *addr)
569
-{
570
-  int i;
571
-  MD5_CTX ctx;
572
-  uint8_t hash[16];
573
-
574
-  if(data->head.flags & MAKUO_FLAG_CRYPT){
575
-    if(!moption.cryptena){
576
-      lprintf(0, "mrecv_decrypt: recv encrypt packet from %s. I have not key!", inet_ntoa(addr->sin_addr));
577
-      return(-1);
578
-    }
579
-    if(data->head.szdata){
580
-      for(i=0;i<data->head.szdata;i+=8){
581
-        BF_decrypt((BF_LONG *)(data->data + i), &EncKey);
582
-      }
583
-      MD5_Init(&ctx);
584
-      MD5_Update(&ctx, data->data, data->head.szdata);
585
-      MD5_Final(hash, &ctx);
586
-      if(memcmp(hash,data->head.hash,16)){
587
-        lprintf(0, "mrecv_decrypt: protocol checksum error from %s\n", inet_ntoa(addr->sin_addr));
588
-        return(-1);
589
-      }
590
-    }
591
-  }
592
-  return(0);
593
-}
594
-
595
-static int mrecv_packet(int s, mdata *data, struct sockaddr_in *addr)
596
-{
597
-  int recvsize;
598
-  socklen_t addr_len;
599
-
600
-  while(1){
601
-    addr_len = sizeof(struct sockaddr_in);
602
-    recvsize = recvfrom(s, data, sizeof(mdata), 0, (struct sockaddr *)addr, &addr_len);
603
-    if(recvsize != -1){
563
+      mrecv_req_md5_close(m, data, addr);
604 564
       break;
605
-    }else{
606
-      if(errno == EAGAIN || errno == EINTR){
607
-        continue;
608
-      }else{
609
-        lprintf(0, "mrecv_packets: recv error from %s\n", inet_ntoa(addr->sin_addr));
610
-        return(-1);
611
-      }
612
-    }
613
-  }
614
-  if(recvsize < sizeof(data->head)){
615
-    lprintf(0, "mrecv: recv head size error\n");
616
-    return(-1);
617
-  }
618
-
619
-  /* ヘッダをホストバイトオーダに変換する */
620
-  data->head.szdata = ntohs(data->head.szdata);
621
-  data->head.flags  = ntohs(data->head.flags);
622
-  data->head.reqid  = ntohl(data->head.reqid);
623
-  data->head.seqno  = ntohl(data->head.seqno);
624
-
625
-  /* プロトコルバージョンが一致しないパケットは破棄する */
626
-  if(data->head.vproto != PROTOCOL_VERSION){
627
-    lprintf(0, "mrecv_packet: protocol version error(%d != %d) from %s\n",
628
-       data->head.vproto, PROTOCOL_VERSION, inet_ntoa(addr->sin_addr));
629
-    return(-1);
630 565
   }
631
-
632
-  return(mrecv_decrypt(data, addr));
633 566
 }
634 567
 
635
-/*
636
- *  通信断などで残ってしまったオブジェクトを掃除
637
- */
638
-void mrecv_gc()
568
+static void mrecv_req(mdata *data, struct sockaddr_in *addr)
639 569
 {
640
-  mhost *t = members;
641
-  mfile *m = mftop[1]; 
642
-  while(m){
643
-    if(mtimeout(&(m->lastrecv), MAKUO_RECV_GCWAIT)){
644
-      lprintf(0,"mrecv_gc: mfile object GC state=%d %s\n", m->mdata.head.nstate, m->fn);
645
-      m = mrecv_mfdel(m);
646
-      continue;
647
-    }
648
-    m = m->next;
649
-  }
650
-
651
-  /* pong timeout */
652
-  while(t){
653
-    if(!mtimeout(&(t->lastrecv), MAKUO_PONG_TIMEOUT)){
654
-      t = t->next;
655
-    }else{
656
-      lprintf(0,"mrecv_gc: pong timeout %s\n", t->hostname);
657
-      if(t->next){
658
-        t = t->next;
659
-        member_del(t->prev);
660
-      }else{
661
-        member_del(t);
662
-        t = NULL;
663
-     } 
664
-    }      
665
-  }
666
-}
667
-
668
-/*
669
- *  ソケットからデータを読み込んでmdata構造体に格納
670
- *  オペコードによってそれぞれの処理に分岐する
671
- */
672
-void mrecv(int s)
673
-{
674
-  mdata  data;
675
-  struct sockaddr_in addr;
676
-
677
-  if(mrecv_packet(s, &data, &addr) == -1){
678
-    return;
679
-  }
680
-  switch(data.head.opcode){
570
+  switch(data->head.opcode){
681 571
     case MAKUO_OP_PING:
682
-      mrecv_ping(&data, &addr);
683
-      break;
684
-    case MAKUO_OP_PONG:
685
-      mrecv_pong(&data, &addr);
572
+      mrecv_req_ping(data, addr);
686 573
       break;
687 574
     case MAKUO_OP_EXIT:
688
-      mrecv_exit(&data, &addr);
689
-      break;
690
-    case MAKUO_OP_ACK:
691
-      mrecv_ack(&data, &addr);
575
+      mrecv_req_exit(data, addr);
692 576
       break;
693 577
     case MAKUO_OP_FILE:
694
-      mrecv_file(&data, &addr);
578
+      mrecv_req_file(data, addr);
695 579
       break;
696 580
     case MAKUO_OP_MD5:
697
-      mrecv_md5(&data, &addr);
581
+      mrecv_req_md5(data, addr);
698 582
       break;
699 583
   }
700 584
 }
701 585
deleted file mode 100644
... ...
@@ -1,21 +0,0 @@
1
-void mrecv_gc();
2
-void mrecv(int s);
3
-static mfile *mrecv_mfdel(mfile *m);
4
-static int    mrecv_packet(int s, mdata *data, struct sockaddr_in *addr);
5
-static void   mrecv_ping(mdata *data, struct sockaddr_in *addr);
6
-static void   mrecv_exit(mdata *data, struct sockaddr_in *addr);
7
-static int    mrecv_file_data(mfile *m,  mdata *r);
8
-static int    mrecv_file_break(mfile *m, mdata *r);
9
-static int    mrecv_file_open(mfile *m, mdata *r);
10
-static int    mrecv_file_close(mfile *m, mdata *r);
11
-static int    mrecv_file_mark(mfile *m, mdata *r);
12
-static int    mrecv_file_next(mfile *m,  mdata *r);
13
-static mfile *mrecv_file_stat(mdata *data, struct sockaddr_in *addr);
14
-static void   mrecv_file(mdata *data, struct sockaddr_in *addr);
15
-static void   mrecv_ack_file(mfile *m, mhost *h, mdata *data);
16
-static void   mrecv_ack_md5(mfile *m, mhost *h, mdata *data);
17
-static void   mrecv_ack(mdata *data, struct sockaddr_in *addr);
18
-static void   mrecv_md5_open(mfile *m, mdata *data, struct sockaddr_in *addr);
19
-static void   mrecv_md5_close(mfile *m, mdata *data, struct sockaddr_in *addr);
20
-static void   mrecv_md5(mdata *data, struct sockaddr_in *addr);
21
-static int    mrecv_decrypt(mdata *data, struct sockaddr_in *addr);
... ...
@@ -504,25 +504,35 @@ static void msend_retry(mfile *m)
504 504
  */
505 505
 void msend(int s, mfile *m)
506 506
 {
507
-  if(!m)
507
+  if(!m){
508 508
     return;
509
+  }
509 510
   msend_retry(m);
510 511
   mtimeget(&m->lastsend);
511
-  switch(m->mdata.head.opcode){
512
-    case MAKUO_OP_PING:
513
-    case MAKUO_OP_PONG:
514
-    case MAKUO_OP_EXIT:
515
-      msend_shot(s, m);
516
-      break;
517
-    case MAKUO_OP_ACK:
518
-      msend_ack(s, m);
519
-      break;
520
-    case MAKUO_OP_FILE:
521
-      msend_file(s, m);
522
-      break;
523
-    case MAKUO_OP_MD5:
524
-      msend_md5(s, m);
525
-      break;
512
+  if(m->mdata.head.flags & MAKUO_FLAG_ACK){
513
+    /* ack */
514
+    switch(m->mdata.head.opcode){
515
+      case MAKUO_OP_PING:
516
+        msend_shot(s, m);
517
+        break;
518
+      case MAKUO_OP_FILE:
519
+      case MAKUO_OP_MD5:
520
+        msend_ack(s, m);
521
+        break;
522
+    }
523
+  }else{
524
+    /* req */
525
+    switch(m->mdata.head.opcode){
526
+      case MAKUO_OP_PING:
527
+      case MAKUO_OP_EXIT:
528
+        msend_shot(s, m);
529
+        break;
530
+      case MAKUO_OP_FILE:
531
+        msend_file(s, m);
532
+        break;
533
+      case MAKUO_OP_MD5:
534
+        msend_md5(s, m);
535
+        break;
536
+    }
526 537
   }
527 538
 }
528
-