project_files/frontlib/net/netbase.c
changeset 10017 de822cd3df3a
parent 7497 7e1d72fc03c7
equal deleted inserted replaced
10015:4feced261c68 10017:de822cd3df3a
    29 #include <stdio.h>
    29 #include <stdio.h>
    30 
    30 
    31 #define NET_READBUFFER_LIMIT (1024*1024)
    31 #define NET_READBUFFER_LIMIT (1024*1024)
    32 
    32 
    33 struct _flib_netbase {
    33 struct _flib_netbase {
    34 	flib_vector *readBuffer;
    34     flib_vector *readBuffer;
    35 	flib_tcpsocket *sock;
    35     flib_tcpsocket *sock;
    36 };
    36 };
    37 
    37 
    38 flib_netbase *flib_netbase_create(const char *server, uint16_t port) {
    38 flib_netbase *flib_netbase_create(const char *server, uint16_t port) {
    39 	if(log_badargs_if2(server==NULL, port==0)) {
    39     if(log_badargs_if2(server==NULL, port==0)) {
    40 		return NULL;
    40         return NULL;
    41 	}
    41     }
    42 
    42 
    43 	flib_netbase *result = NULL;
    43     flib_netbase *result = NULL;
    44 	flib_netbase *newNet =  flib_calloc(1, sizeof(flib_netbase));
    44     flib_netbase *newNet =  flib_calloc(1, sizeof(flib_netbase));
    45 
    45 
    46 	if(newNet) {
    46     if(newNet) {
    47 		newNet->readBuffer = flib_vector_create();
    47         newNet->readBuffer = flib_vector_create();
    48 		newNet->sock = flib_socket_connect(server, port);
    48         newNet->sock = flib_socket_connect(server, port);
    49 		if(newNet->readBuffer && newNet->sock) {
    49         if(newNet->readBuffer && newNet->sock) {
    50 			flib_log_i("Connected to server %s:%u", server, (unsigned)port);
    50             flib_log_i("Connected to server %s:%u", server, (unsigned)port);
    51 			result = newNet;
    51             result = newNet;
    52 			newNet = NULL;
    52             newNet = NULL;
    53 		}
    53         }
    54 	}
    54     }
    55 	flib_netbase_destroy(newNet);
    55     flib_netbase_destroy(newNet);
    56 
    56 
    57 	return result;
    57     return result;
    58 }
    58 }
    59 
    59 
    60 void flib_netbase_destroy(flib_netbase *net) {
    60 void flib_netbase_destroy(flib_netbase *net) {
    61 	if(net) {
    61     if(net) {
    62 		flib_socket_close(net->sock);
    62         flib_socket_close(net->sock);
    63 		flib_vector_destroy(net->readBuffer);
    63         flib_vector_destroy(net->readBuffer);
    64 		free(net);
    64         free(net);
    65 	}
    65     }
    66 }
    66 }
    67 
    67 
    68 bool flib_netbase_connected(flib_netbase *net) {
    68 bool flib_netbase_connected(flib_netbase *net) {
    69 	if(!log_badargs_if(net==NULL) && net->sock) {
    69     if(!log_badargs_if(net==NULL) && net->sock) {
    70 		return true;
    70         return true;
    71 	}
    71     }
    72 	return false;
    72     return false;
    73 }
    73 }
    74 
    74 
    75 /**
    75 /**
    76  * Parses and returns a message, and removes it from the vector.
    76  * Parses and returns a message, and removes it from the vector.
    77  */
    77  */
    78 static flib_netmsg *parseMessage(flib_vector *vec) {
    78 static flib_netmsg *parseMessage(flib_vector *vec) {
    79 	const uint8_t *partStart = flib_vector_data(vec);
    79     const uint8_t *partStart = flib_vector_data(vec);
    80 	const uint8_t *end = partStart+flib_vector_size(vec);
    80     const uint8_t *end = partStart+flib_vector_size(vec);
    81 	flib_netmsg *result = flib_netmsg_create();
    81     flib_netmsg *result = flib_netmsg_create();
    82 	if(!result) {
    82     if(!result) {
    83 		return NULL;
    83         return NULL;
    84 	}
    84     }
    85 
    85 
    86 	while(1) {
    86     while(1) {
    87 		const uint8_t *partEnd = memchr(partStart, '\n', end-partStart);
    87         const uint8_t *partEnd = memchr(partStart, '\n', end-partStart);
    88 		if(!partEnd) {
    88         if(!partEnd) {
    89 			// message incomplete
    89             // message incomplete
    90 			flib_netmsg_destroy(result);
    90             flib_netmsg_destroy(result);
    91 			return NULL;
    91             return NULL;
    92 		} else if(partEnd-partStart == 0) {
    92         } else if(partEnd-partStart == 0) {
    93 			// Zero-length part, message end marker. Remove the message from the vector.
    93             // Zero-length part, message end marker. Remove the message from the vector.
    94 			uint8_t *vectorStart = flib_vector_data(vec);
    94             uint8_t *vectorStart = flib_vector_data(vec);
    95 			size_t msgLen = partEnd+1-vectorStart;
    95             size_t msgLen = partEnd+1-vectorStart;
    96 			memmove(vectorStart, partEnd+1, flib_vector_size(vec)-msgLen);
    96             memmove(vectorStart, partEnd+1, flib_vector_size(vec)-msgLen);
    97 			flib_vector_resize(vec, flib_vector_size(vec)-msgLen);
    97             flib_vector_resize(vec, flib_vector_size(vec)-msgLen);
    98 			return result;
    98             return result;
    99 		} else {
    99         } else {
   100 			if(flib_netmsg_append_part(result, partStart, partEnd-partStart)) {
   100             if(flib_netmsg_append_part(result, partStart, partEnd-partStart)) {
   101 				flib_netmsg_destroy(result);
   101                 flib_netmsg_destroy(result);
   102 				return NULL;
   102                 return NULL;
   103 			}
   103             }
   104 			partStart = partEnd+1; // Skip the '\n'
   104             partStart = partEnd+1; // Skip the '\n'
   105 		}
   105         }
   106 	}
   106     }
   107 	return NULL; // Never reached
   107     return NULL; // Never reached
   108 }
   108 }
   109 
   109 
   110 /**
   110 /**
   111  * Receive some bytes and add them to the buffer.
   111  * Receive some bytes and add them to the buffer.
   112  * Returns the number of bytes received.
   112  * Returns the number of bytes received.
   113  * Automatically closes the socket if an error occurs
   113  * Automatically closes the socket if an error occurs
   114  * and sets sock=NULL.
   114  * and sets sock=NULL.
   115  */
   115  */
   116 static int receiveToBuffer(flib_netbase *net) {
   116 static int receiveToBuffer(flib_netbase *net) {
   117 	uint8_t buffer[256];
   117     uint8_t buffer[256];
   118 	if(!net->sock) {
   118     if(!net->sock) {
   119 		return 0;
   119         return 0;
   120 	} else if(flib_vector_size(net->readBuffer) > NET_READBUFFER_LIMIT) {
   120     } else if(flib_vector_size(net->readBuffer) > NET_READBUFFER_LIMIT) {
   121 		flib_log_e("Net connection closed: Net message too big");
   121         flib_log_e("Net connection closed: Net message too big");
   122 		flib_socket_close(net->sock);
   122         flib_socket_close(net->sock);
   123 		net->sock = NULL;
   123         net->sock = NULL;
   124 		return 0;
   124         return 0;
   125 	} else {
   125     } else {
   126 		int size = flib_socket_nbrecv(net->sock, buffer, sizeof(buffer));
   126         int size = flib_socket_nbrecv(net->sock, buffer, sizeof(buffer));
   127 		if(size>=0 && !flib_vector_append(net->readBuffer, buffer, size)) {
   127         if(size>=0 && !flib_vector_append(net->readBuffer, buffer, size)) {
   128 			return size;
   128             return size;
   129 		} else {
   129         } else {
   130 			flib_socket_close(net->sock);
   130             flib_socket_close(net->sock);
   131 			net->sock = NULL;
   131             net->sock = NULL;
   132 			return 0;
   132             return 0;
   133 		}
   133         }
   134 	}
   134     }
   135 }
   135 }
   136 
   136 
   137 flib_netmsg *flib_netbase_recv_message(flib_netbase *net) {
   137 flib_netmsg *flib_netbase_recv_message(flib_netbase *net) {
   138 	if(log_badargs_if(net==NULL)) {
   138     if(log_badargs_if(net==NULL)) {
   139 		return NULL;
   139         return NULL;
   140 	}
   140     }
   141 
   141 
   142 	flib_netmsg *msg;
   142     flib_netmsg *msg;
   143 	while(!(msg=parseMessage(net->readBuffer))
   143     while(!(msg=parseMessage(net->readBuffer))
   144 			&& receiveToBuffer(net)) {}
   144             && receiveToBuffer(net)) {}
   145 
   145 
   146 	if(msg) {
   146     if(msg) {
   147 		return msg;
   147         return msg;
   148 	} else if(!net->sock && flib_vector_size(net->readBuffer)>0) {
   148     } else if(!net->sock && flib_vector_size(net->readBuffer)>0) {
   149 		// Connection is down and we didn't get a complete message, just flush the rest.
   149         // Connection is down and we didn't get a complete message, just flush the rest.
   150 		flib_vector_resize(net->readBuffer, 0);
   150         flib_vector_resize(net->readBuffer, 0);
   151 	}
   151     }
   152 	return NULL;
   152     return NULL;
   153 }
   153 }
   154 
   154 
   155 static void logSentMsg(const uint8_t *data, size_t len) {
   155 static void logSentMsg(const uint8_t *data, size_t len) {
   156 	if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) {
   156     if(flib_log_isActive(FLIB_LOGLEVEL_DEBUG)) {
   157 		flib_log_d("[NET OUT][%03u]%*.*s",(unsigned)len, (unsigned)len, (unsigned)len, data);
   157         flib_log_d("[NET OUT][%03u]%*.*s",(unsigned)len, (unsigned)len, (unsigned)len, data);
   158 	}
   158     }
   159 }
   159 }
   160 
   160 
   161 int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len) {
   161 int flib_netbase_send_raw(flib_netbase *net, const void *data, size_t len) {
   162 	if(log_badargs_if2(net==NULL, data==NULL && len>0)) {
   162     if(log_badargs_if2(net==NULL, data==NULL && len>0)) {
   163 		return -1;
   163         return -1;
   164 	}
   164     }
   165 	if(!net->sock) {
   165     if(!net->sock) {
   166 		flib_log_w("flib_netbase_send_raw: Not connected.");
   166         flib_log_w("flib_netbase_send_raw: Not connected.");
   167 		return -1;
   167         return -1;
   168 	}
   168     }
   169 
   169 
   170 	if(flib_socket_send(net->sock, data, len) == len) {
   170     if(flib_socket_send(net->sock, data, len) == len) {
   171 		logSentMsg(data, len);
   171         logSentMsg(data, len);
   172 		return 0;
   172         return 0;
   173 	} else {
   173     } else {
   174 		flib_log_w("Failed or incomplete write: net connection lost.");
   174         flib_log_w("Failed or incomplete write: net connection lost.");
   175 		flib_socket_close(net->sock);
   175         flib_socket_close(net->sock);
   176 		net->sock = NULL;
   176         net->sock = NULL;
   177 		return -1;
   177         return -1;
   178 	}
   178     }
   179 }
   179 }
   180 
   180 
   181 int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg) {
   181 int flib_netbase_send_message(flib_netbase *net, const flib_netmsg *msg) {
   182 	if(log_badargs_if2(net==NULL, msg==NULL)) {
   182     if(log_badargs_if2(net==NULL, msg==NULL)) {
   183 		return -1;
   183         return -1;
   184 	}
   184     }
   185 
   185 
   186 	size_t totalSize = 0;
   186     size_t totalSize = 0;
   187 	for(int i=0; i<msg->partCount; i++) {
   187     for(int i=0; i<msg->partCount; i++) {
   188 		totalSize += strlen(msg->parts[i]) + 1;
   188         totalSize += strlen(msg->parts[i]) + 1;
   189 	}
   189     }
   190 	totalSize++; // Last part ends in two '\n' instead of one
   190     totalSize++; // Last part ends in two '\n' instead of one
   191 
   191 
   192 	uint8_t *buffer = flib_malloc(totalSize);
   192     uint8_t *buffer = flib_malloc(totalSize);
   193 	if(!buffer) {
   193     if(!buffer) {
   194 		return -1;
   194         return -1;
   195 	}
   195     }
   196 	size_t pos = 0;
   196     size_t pos = 0;
   197 	for(int i=0; i<msg->partCount; i++) {
   197     for(int i=0; i<msg->partCount; i++) {
   198 		size_t partsize = strlen(msg->parts[i]);
   198         size_t partsize = strlen(msg->parts[i]);
   199 		memcpy(buffer+pos, msg->parts[i], partsize);
   199         memcpy(buffer+pos, msg->parts[i], partsize);
   200 		pos += partsize;
   200         pos += partsize;
   201 		buffer[pos++] = '\n';
   201         buffer[pos++] = '\n';
   202 	}
   202     }
   203 	buffer[pos++] = '\n';
   203     buffer[pos++] = '\n';
   204 	return flib_netbase_send_raw(net, buffer, pos);
   204     return flib_netbase_send_raw(net, buffer, pos);
   205 }
   205 }
   206 
   206 
   207 int flib_netbase_sendf(flib_netbase *net, const char *format, ...) {
   207 int flib_netbase_sendf(flib_netbase *net, const char *format, ...) {
   208 	int result = -1;
   208     int result = -1;
   209 	if(!log_badargs_if2(net==NULL, format==NULL)) {
   209     if(!log_badargs_if2(net==NULL, format==NULL)) {
   210 		va_list argp;
   210         va_list argp;
   211 		va_start(argp, format);
   211         va_start(argp, format);
   212 		char *buffer = flib_vasprintf(format, argp);
   212         char *buffer = flib_vasprintf(format, argp);
   213 		if(buffer) {
   213         if(buffer) {
   214 			result = flib_netbase_send_raw(net, buffer, strlen(buffer));
   214             result = flib_netbase_send_raw(net, buffer, strlen(buffer));
   215 		}
   215         }
   216 		free(buffer);
   216         free(buffer);
   217 		va_end(argp);
   217         va_end(argp);
   218 	}
   218     }
   219 	return result;
   219     return result;
   220 }
   220 }
   221 
   221 
   222 flib_netmsg *flib_netmsg_create() {
   222 flib_netmsg *flib_netmsg_create() {
   223 	flib_netmsg *result = flib_calloc(1, sizeof(flib_netmsg));
   223     flib_netmsg *result = flib_calloc(1, sizeof(flib_netmsg));
   224 	if(result) {
   224     if(result) {
   225 		result->partCount = 0;
   225         result->partCount = 0;
   226 		result->parts = NULL;
   226         result->parts = NULL;
   227 		return result;
   227         return result;
   228 	} else {
   228     } else {
   229 		return NULL;
   229         return NULL;
   230 	}
   230     }
   231 }
   231 }
   232 
   232 
   233 void flib_netmsg_destroy(flib_netmsg *msg) {
   233 void flib_netmsg_destroy(flib_netmsg *msg) {
   234 	if(msg) {
   234     if(msg) {
   235 		for(int i=0; i<msg->partCount; i++) {
   235         for(int i=0; i<msg->partCount; i++) {
   236 			free(msg->parts[i]);
   236             free(msg->parts[i]);
   237 		}
   237         }
   238 		free(msg->parts);
   238         free(msg->parts);
   239 		free(msg);
   239         free(msg);
   240 	}
   240     }
   241 }
   241 }
   242 
   242 
   243 int flib_netmsg_append_part(flib_netmsg *msg, const void *part, size_t partlen) {
   243 int flib_netmsg_append_part(flib_netmsg *msg, const void *part, size_t partlen) {
   244 	int result = -1;
   244     int result = -1;
   245 	if(!log_badargs_if2(msg==NULL, part==NULL && partlen>0)) {
   245     if(!log_badargs_if2(msg==NULL, part==NULL && partlen>0)) {
   246 		char **newParts = realloc(msg->parts, (msg->partCount+1)*sizeof(*msg->parts));
   246         char **newParts = realloc(msg->parts, (msg->partCount+1)*sizeof(*msg->parts));
   247 		if(newParts) {
   247         if(newParts) {
   248 			msg->parts = newParts;
   248             msg->parts = newParts;
   249 			msg->parts[msg->partCount] = flib_malloc(partlen+1);
   249             msg->parts[msg->partCount] = flib_malloc(partlen+1);
   250 			if(msg->parts[msg->partCount]) {
   250             if(msg->parts[msg->partCount]) {
   251 				memcpy(msg->parts[msg->partCount], part, partlen);
   251                 memcpy(msg->parts[msg->partCount], part, partlen);
   252 				msg->parts[msg->partCount][partlen] = 0;
   252                 msg->parts[msg->partCount][partlen] = 0;
   253 				msg->partCount++;
   253                 msg->partCount++;
   254 				result = 0;
   254                 result = 0;
   255 			}
   255             }
   256 		}
   256         }
   257 	}
   257     }
   258 	return result;
   258     return result;
   259 }
   259 }