summaryrefslogtreecommitdiff
path: root/net/mptcp/token.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mptcp/token.c')
-rw-r--r--net/mptcp/token.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/net/mptcp/token.c b/net/mptcp/token.c
index 7d8106026081..8b47c4bb1c6b 100644
--- a/net/mptcp/token.c
+++ b/net/mptcp/token.c
@@ -83,6 +83,18 @@ static bool __token_bucket_busy(struct token_bucket *t, u32 token)
__token_lookup_req(t, token) || __token_lookup_msk(t, token);
}
+static void mptcp_crypto_key_gen_sha(u64 *key, u32 *token, u64 *idsn)
+{
+ /* we might consider a faster version that computes the key as a
+ * hash of some information available in the MPTCP socket. Use
+ * random data at the moment, as it's probably the safest option
+ * in case multiple sockets are opened in different namespaces at
+ * the same time.
+ */
+ get_random_bytes(key, sizeof(u64));
+ mptcp_crypto_key_sha(*key, token, idsn);
+}
+
/**
* mptcp_token_new_request - create new key/idsn/token for subflow_request
* @req: the request socket
@@ -97,14 +109,12 @@ static bool __token_bucket_busy(struct token_bucket *t, u32 token)
int mptcp_token_new_request(struct request_sock *req)
{
struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
- int retries = TOKEN_MAX_RETRIES;
struct token_bucket *bucket;
u32 token;
-again:
- mptcp_crypto_key_gen_sha(&subflow_req->local_key,
- &subflow_req->token,
- &subflow_req->idsn);
+ mptcp_crypto_key_sha(subflow_req->local_key,
+ &subflow_req->token,
+ &subflow_req->idsn);
pr_debug("req=%p local_key=%llu, token=%u, idsn=%llu\n",
req, subflow_req->local_key, subflow_req->token,
subflow_req->idsn);
@@ -114,9 +124,7 @@ again:
spin_lock_bh(&bucket->lock);
if (__token_bucket_busy(bucket, token)) {
spin_unlock_bh(&bucket->lock);
- if (!--retries)
- return -EBUSY;
- goto again;
+ return -EBUSY;
}
hlist_nulls_add_head_rcu(&subflow_req->token_node, &bucket->req_chain);
@@ -196,6 +204,32 @@ void mptcp_token_accept(struct mptcp_subflow_request_sock *req,
spin_unlock_bh(&bucket->lock);
}
+bool mptcp_token_exists(u32 token)
+{
+ struct hlist_nulls_node *pos;
+ struct token_bucket *bucket;
+ struct mptcp_sock *msk;
+ struct sock *sk;
+
+ rcu_read_lock();
+ bucket = token_bucket(token);
+
+again:
+ sk_nulls_for_each_rcu(sk, pos, &bucket->msk_chain) {
+ msk = mptcp_sk(sk);
+ if (READ_ONCE(msk->token) == token)
+ goto found;
+ }
+ if (get_nulls_value(pos) != (token & token_mask))
+ goto again;
+
+ rcu_read_unlock();
+ return false;
+found:
+ rcu_read_unlock();
+ return true;
+}
+
/**
* mptcp_token_get_sock - retrieve mptcp connection sock using its token
* @token: token of the mptcp connection to retrieve
@@ -356,7 +390,7 @@ void __init mptcp_token_init(void)
sizeof(struct token_bucket),
0,
20,/* one slot per 1MB of memory */
- 0,
+ HASH_ZERO,
NULL,
&token_mask,
0,