|
15 | 15 | #define IFACE_STATE_DOWN BIT(0) |
16 | 16 | #define IFACE_STATE_CONFIGURED BIT(1) |
17 | 17 |
|
| 18 | +static atomic_t active_num_conn; |
| 19 | + |
18 | 20 | struct interface { |
19 | 21 | struct task_struct *ksmbd_kthread; |
20 | 22 | struct socket *ksmbd_socket; |
@@ -185,8 +187,10 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk) |
185 | 187 | struct tcp_transport *t; |
186 | 188 |
|
187 | 189 | t = alloc_transport(client_sk); |
188 | | - if (!t) |
| 190 | + if (!t) { |
| 191 | + sock_release(client_sk); |
189 | 192 | return -ENOMEM; |
| 193 | + } |
190 | 194 |
|
191 | 195 | csin = KSMBD_TCP_PEER_SOCKADDR(KSMBD_TRANS(t)->conn); |
192 | 196 | if (kernel_getpeername(client_sk, csin) < 0) { |
@@ -239,6 +243,15 @@ static int ksmbd_kthread_fn(void *p) |
239 | 243 | continue; |
240 | 244 | } |
241 | 245 |
|
| 246 | + if (server_conf.max_connections && |
| 247 | + atomic_inc_return(&active_num_conn) >= server_conf.max_connections) { |
| 248 | + pr_info_ratelimited("Limit the maximum number of connections(%u)\n", |
| 249 | + atomic_read(&active_num_conn)); |
| 250 | + atomic_dec(&active_num_conn); |
| 251 | + sock_release(client_sk); |
| 252 | + continue; |
| 253 | + } |
| 254 | + |
242 | 255 | ksmbd_debug(CONN, "connect success: accepted new connection\n"); |
243 | 256 | client_sk->sk->sk_rcvtimeo = KSMBD_TCP_RECV_TIMEOUT; |
244 | 257 | client_sk->sk->sk_sndtimeo = KSMBD_TCP_SEND_TIMEOUT; |
@@ -368,6 +381,8 @@ static int ksmbd_tcp_writev(struct ksmbd_transport *t, struct kvec *iov, |
368 | 381 | static void ksmbd_tcp_disconnect(struct ksmbd_transport *t) |
369 | 382 | { |
370 | 383 | free_transport(TCP_TRANS(t)); |
| 384 | + if (server_conf.max_connections) |
| 385 | + atomic_dec(&active_num_conn); |
371 | 386 | } |
372 | 387 |
|
373 | 388 | static void tcp_destroy_socket(struct socket *ksmbd_socket) |
|
0 commit comments